Lazarus - why doesn't this work with ShowModal? - modal-dialog

I have two forms in Lazarus. one is frmMain and the other is frmSub1. both have a text box.
The following code works. i.e., on clicking a button on frmMain, the value
procedure TfrmMain.cmdShowClick(Sender: TObject);
begin
frmSub1.Show ;
frmSub1.txtAns.text := txtMark.Text;
end;
But when I replace .Show with .ShowModal, it shows the form but frmSub1.txtAns is blank.
Any idea why this is so?

Thats because ShowModal is blocking call, ie the line frmSub1.txtAns.text := txtMark.Text; wont execute until it returns. You have to switch the order of statements, following should work as you expect:
procedure TfrmMain.cmdShowClick(Sender: TObject);
begin
frmSub1.txtAns.text := txtMark.Text;
frmSub1.ShowModal;
end;

Related

PGSQL: Function argument not being passed correctly

I am attempting to search the "message" column of a table for any instance of a tag mentioned (like " #testing1 " for example).
When I manually enter the query it works but I think that I'm not understanding how to concat the tag properly:
This works:
select amount from donations where message like #testing1
But this does not:
CREATE OR REPLACE FUNCTION sum_tag(
tag TEXT)
RETURNS VOID AS $$
BEGIN
select amount from donations where message like CONCAT ('%#', tag, '%');
END; $$
LANGUAGE plpgsql;
The above is what is in the begin and end statements inside of the function sum_tag(tag text).
My intent is that I am trying to capture the tag whether it is in the message as "#testing1 this is a message" or "This is a message #testing1" and then use that as an identifier to sum up all of the amount column values for the associated rows.
Update 1
I have attempted to use the suggestion as noted in the comments but It did not seem to work. The updated function was entered as:
CREATE OR REPLACE FUNCTION sum_tag(
tag TEXT)
RETURNS VOID AS $$
BEGIN
EXECUTE format('select amount from donations where message like %s', tag);
END; $$
LANGUAGE plpgsql;
This did not work either. If I am understanding, the entire statement needs to be in single quotes and %s is the correct way to call the argument as it is a text string. I appreciate your explanation and places to look.

Access object on another form with the form as a variable

I'm writing a program in Delphi which includes creating the same dynamic object on multiple forms (never simultaneously), and then a procedure in another unit writes certain text to it.
How the object (TMemo) is created:
memHulp := TMemo.Create(frmHome);
with memHulp do
begin
Parent := frmHome;
Top := 208;
Left := 88;
Height := 98;
Width := 209;
ReadOnly := True;
end;
The properties aren't that important, it's just to show the creation of the object and how it is referred to.
Now, I need to read certain text into the memo from a text file, which there is no problem with, but the problem comes when there are different forms involved that all use that same self-defined procedure.
It's easy to say frmHome.memHulp.Lines.Add() in this particular case, but when I need it to display the text on the memo named exactly the same in all cases, but on a different form, I'm having some trouble.
The frmHome part needs to be a variable. So I tried this:
var
Form: TForm;
begin
Form := Application.FindComponent('frmHome') as TForm;
end;
That doesn't warn me or give an error, but as soon as I try to say Form.memHulp.Lines.Add(), it does not work, and I understand that it probably doesn't have any properties for Form, but how do I make it look at the correct place? I need to be able to tell the program to look on whichever form name I pass as a parameter into the FindComponent() part.
If this is completely not possible, please suggest other solutions to achieve the same.
Form.memHulp doesn't work because Form is a plain vanilla TForm pointer, and TForm doesn't have a memHulp member. You could use Form.FindComponent('memHulp') instead, since you are assigning the TForm object as the Memo's Owner, but that would require you to assign a Name to the Memo, eg:
memHulp := TMemo.Create(frmHome);
with memHulp do
begin
Parent := frmHome;
Name := 'memHulp';
...
end;
Alternatively, since you say you are creating only 1 Memo object at a time, you could simply make memHulp be a global variable in some unit's interface section, and then you would have direct access to it without having to hunt for it.

Can't see raise messages in DBeaver or PgAdmin

When i execute the function below (in the picture), i can't find the raise message anywhere even in execution logs: is there anyway to make it appear.
script:
SELECT helloworld('myname');
CREATE OR REPLACE FUNCTION helloWorld(name text) RETURNS void AS $helloWorld$
DECLARE
BEGIN
RAISE LOG 'Hello, %', name;
END;
$helloWorld$ LANGUAGE plpgsql;
Messages with the level LOG typicall don't get sent to the client.
Either use RAISE NOTICE or set client_min_messages to log.
also dont do a basic mistake like me that to see the raise notice messages inside function, you first have to call that function by select public.helloworld()

Can't call Postgresql function which should return text value

I have a little problem when calling a Postgresql function in Delphi with FireDAC.
The Postgresql function has the following definition:
CREATE OR REPLACE FUNCTION public."pgpDecryptMe" (
todecode text
)
RETURNS text AS
$body$
DECLARE
PGPPrivate TEXT;
BEGIN
...
So it expects a "text" value and returns a "text" value.
I can call it with a long text parameter (over 900 character) and it returns the correct value in any sql admin tool without any problems.
select "pgpDecryptMe"('c1c04c030...a378624e6a659a20765') as Decrypt
But calling it in Delphi with the following code:
PGQuery.SQL.Text := 'select "pgpDecryptMe"(:test) as testvalue';
PGQuery.ParamByName('test').AsString := 'c1c04c030...a378624e6a659a20765';
PGQuery.Open();
Gives me the following error message:
[FireDAC][DatS]-2. Object [id] is not found
I googled and searched here but can't find any solution for the problem.
It is probably something very small I can't see :-(
I am working with Delphi XE7 and PostgreSQL 9.3
Ok, now I got it working.
It looks like it needed an additional index field name which doesn't really make sense because it just returned one value...
So it worked when I changed my code to the following:
PGQuery.SQL.Text := 'select "pgpDecryptMe"(:test) as testvalue';
PGQuery.ParamByName('test').AsString := 'c1c04c030...a378624e6a659a20765';
PGQuery.IndexFieldNames := 'testvalue';
PGQuery.Open();

passing parameters between forms

Hi everyone i'm trying to passing parameters between forms but i have this error:
frm-92101 there was a failure in the forms server during startup.
I wanna place a button on the EMPLOYEE form that when pressed, will call the EMPLOYEE/DEPENDENT form and automatically query the dependents for the employee being viewed on the EMPLOYEE form.
Icreated the EMPLOYEE Form and add a button.I assigned a trigger when bouton pressed :
DECLARE
pl_id ParamList;
BEGIN
pl_id := Get_Parameter_List('tmpdata');
IF NOT Id_Null(pl_id) THEN
Destroy_Parameter_List( pl_id );
END IF;
pl_id := Create_Parameter_List('tmpdata');
Add_Parameter(pl_id, 'EMPLOYEESSN', TEXT_PARAMETER, :SSN);
Run_Product(FORMS, 'empdepn', SYNCHRONOUS, RUNTIME,
FILESYSTEM, pl_id, NULL);
END;
After that i add a parameter into the EMPLOYEE/DEPENDENT
I created a PARAMETER called EMPLOYEESSN with the code bellow and add a parameter EMPLOYEESSN and add a WHEN-NEW-FORM-INSTANCE trigger :
DECLARE
blk_id Block;
BEGIN
-- Obtain the block ID of the EMPLOYEE block. This is the
-- Master block in the empdepn master/detail form.
blk_id := Find_Block('EMPLOYEE');
IF NOT Id_Null(blk_id) THEN
-- Check to make sure our parameter has a value. If this form
-- were executed by itself, then the parameter will be null.
-- If this form is called from EMPLOYEE then the parameter will
-- be passed along and assigned to: PARAMETER.employeessn
IF (:PARAMETER.employeessn is not null) THEN
-- Since we have a parameter, use it to alter the WHERE Clause
-- property so that it becomes WHERE ssn=:PARAMETER.employeessn
SET_BLOCK_PROPERTY(blk_id,DEFAULT_WHERE,'ssn=' || : PARAMETER.employeessn);
-- Navigate to the EMPLOYEE block and execute a query automatically
GO_BLOCK('EMPLOYEE');
EXECUTE_QUERY;
END IF;
END IF;
END;
Any idea please, thanks for help