Login ProductsSalesSupportDownloadsAbout |
Home » Technical Support » Elevate Web Builder Technical Support » Support Forums » Elevate Web Builder General » View Thread |
Messages 11 to 20 of 22 total |
Waiting For Completion |
Tue, Sep 13 2016 1:36 PM | Permanent Link |
erickengelke | Trinione wrote:
Erick wrote: << In the after load event, you cycle through tdataset using tdataset.first, then tdataset.next until you either find your desired results or you hit tdataset.eof. >> >For instance, from the code below - from a function in another program, how can the value of recFound be returned? The easiest way is to set the 'result' pseudo variable which is what gets returned. procedure TdmDataModule.dsCustomerAfterLoad(Sender: TObject); var recFound: boolean; begin recFound := False; if dsCustomer.RowCount > 0 then recFound := True; result := recFound ; // <<<<<<< HERE end; |
Tue, Sep 13 2016 3:11 PM | Permanent Link |
Trinione | erickengelke wrote:
Trinione wrote: Erick wrote: << In the after load event, you cycle through tdataset using tdataset.first, then tdataset.next until you either find your desired results or you hit tdataset.eof. >> >For instance, from the code below - from a function in another program, how can the value of recFound be returned? << The easiest way is to set the 'result' pseudo variable which is what gets returned. procedure TdmDataModule.dsCustomerAfterLoad(Sender: TObject); var recFound: boolean; begin recFound := False; if dsCustomer.RowCount > 0 then recFound := True; result := recFound ; // <<<<<<< HERE end; >> Erick: As dsAfterLoad event is a Procedure and not a Function, setting 'result' results in an error stating the referenced variable does not exist. |
Tue, Sep 13 2016 3:12 PM | Permanent Link |
Trinione | << I set a callback for afterLoad to a local proc in the calling form. Still think it's a bit ugly but it seems to work. >>
What Squiffy wrote is what I am trying to achieve. |
Tue, Sep 13 2016 3:17 PM | Permanent Link |
Trinione | Trinione wrote:
<< What Squiffy wrote is what I am trying to achieve. >> Just found the chapter in the Manual re: Asynchronous Calls. Reading it now..... |
Tue, Sep 13 2016 4:04 PM | Permanent Link |
Trinione | Trinione wrote:
<< Just found the chapter in the Manual re: Asynchronous Calls. Reading it now..... >> The following works. If no one comments otherwise, I would assume this is the way to accomplish this in EWB. In calling function: ------------------------------ dsCustomer.Params.Add('id=' + cid); async(Database.LoadRows(dsCustomer)); if dsCustomer.RowCount > 0 then result := dsCustomer.Columns['id'].AsInteger; ------------------------------ |
Tue, Sep 13 2016 4:28 PM | Permanent Link |
Raul Team Elevate | On 9/13/2016 4:04 PM, Trinione wrote:
> Trinione wrote: > The following works. If no one comments otherwise, I would assume this is the way to accomplish this in EWB. > In calling function: > ------------------------------ > dsCustomer.Params.Add('id=' + cid); > async(Database.LoadRows(dsCustomer)); > > if dsCustomer.RowCount > 0 then > result := dsCustomer.Columns['id'].AsInteger; > ------------------------------ I'm surprised this works - that does not make sense to me at all. I can see this only working if your dsCustomer has some data already when this function starts. Async call results the function call to be queued up for the UI thread to run next time it processes messages - which is after this function has finished and exited. Callback is the only way to accomplish this properly AFAIK (or timers and modal "please wait" typoe dialog or such but then you need need to some additional tracking to deal with failures and if things take more time that anticiapted and timer fires). Raul |
Tue, Sep 13 2016 5:34 PM | Permanent Link |
Trinione | Rauk wrote:
<< Callback is the only way to accomplish this properly AFAIK >> How are Callbacks done? More specifically, how can a callback be used in this case from a Function calling a dataset's OnLoad event 'result'? |
Tue, Sep 13 2016 10:12 PM | Permanent Link |
Raul Team Elevate | On 9/13/2016 5:34 PM, Trinione wrote:
> How are Callbacks done? > More specifically, how can a callback be used in this case from a Function calling a dataset's OnLoad event 'result'? It really depends what you actually want to achieve and what your current code logic is. Few options i can think of 1. If all your logic is in the same unit (for example on the form) then you simply need to break your code into 2 parts: - part 1 runs forst and call loadrows at the end - part 2 is called from AfterLoad event itself for Example procedure TForm1.CustomerAfterLoad(Sender: TObject); begin MyFunction2; end; This is not really a callback but just way one has to do async - splitting your code into 2 functions. 2. Maybe you want to have a generic unit/class that handles all the data loads so you simply need to call correct callback. One way to handle this is with something like this a. declare a callback function type type TMyCallBackFunc = procedure (RecFound:boolean) of object; b. define actual callback function - this could be set by any other code since it's public public FCustomerLoadCallback:TMyCallBackFunc; c. and when doing loadrows also assign callback FCustomerLoadCallback := HandleCustomerLoadDone; //this is my function d. and in your AfterLoad handler do procedure MyGenericAfterLoad(Sender: TObject); begin if TDataSet(Sender).DataSetName = 'Customer' then begin if assigned(FCustomerLoadCallback) then FCustomerLoadCallback(true); end; //could check other datasets here ... end; this is fairly simplistic fixed callback logic but works well if you simplty need a generic module to handle dataaset loading and allow few callback functions to be called. 3. This is nicest IMHO and most genric since you can have dataset carry callback around with it so it's self contained and thus the actual dataset afterload events can be very generic and they will just call proper callback functions if you have assigned them. Use the Data element and just wrap it in class. You need to make sure that all your callbacks and such are "alive" - i.e. do not assign a callback on a form for example that might get destroyed while LoadRows is still executing. a. define callback function type again and wrapper class type TMyCallBackFunc = procedure (RecFound:boolean) of object; TMyCallBackObject = class(TObject) FuncCallback:TMyCallBackFunc; end; b. when customer dataset is created also associate the Data element - i'm doing it all when loading rows but your app logic will defined how to run this myCB := TMyCallBackObject.Create; myCB.FuncCallback := HandleCustomerLoadDone; //assign callback Customer.Data := myCB; //assign your class to dataset database.loadrows(Customer); c. in afterload you would do something like this dsCB := TMyCallBackObject(TDataSet(Sender).Data); if assigned(dsCB) then begin if assigned(dsCB.FuncCallback) then dsCB.FuncCallback(true); end; Note that in all of these cases you should also handle OnLoadError event and act appropriately (again you can have callback for that). Let me know if any of this helps and if you have any other questions Raul |
Wed, Sep 14 2016 12:33 PM | Permanent Link |
Tim Young [Elevate Software] Elevate Software, Inc. timyoung@elevatesoft.com | << I mean how can I get to the calling Function program a value, True or False in this case - but it could be a string or integer, and value really. >> Just add a public Boolean member variable (CustomersFound) to your database instance, and then set the variable to False in the BeforeLoad, and then set it accordingly in the AfterLoad. Or, you could do it way easier and just have the other areas of the application test the RowCount property of the dataset in question. The functionality is equivalent. I sense that what you're looking for is a way to make this process synchronous, which will *not* be possible in a browser environment. Tim Young Elevate Software www.elevatesoft.com |
Wed, Sep 14 2016 5:10 PM | Permanent Link |
Trinione | Raul:
Thank you for your detailed response. It has made me realise this is not as simple as I initially thought as the coding is just out of reach for me as a developing Object Pascal developer. Of the three, I like Option 3 and shall give it a go. I shall use the included sample Customer table as a test. Basically, this is what I need to accomplish: 1- Use an unbound Grid with checkboxes in column 1 and RequestedCustomerID value in Column2. 2 - Scroll thru the rows and for those items selected check the RequestedCustomerID from the grid's Column2. 3 - Create tabs for each selected Customer IDs after checking that the Customer ID record does in fact exist. NOTE, the grid is not created from the database, so the customer ID number may or may not exist in the database - hence the FindCustomerID check that is the reason for my wanting to know about this Callback ability. Thus far, (similar to your Suggestion #1) I am using a direct call back to a function to create that tabs I have the ability to check on one item by double-clicking, haven't tested in a loop as yet. |
« Previous Page | Page 2 of 3 | Next Page » |
Jump to Page: 1 2 3 |
This web page was last updated on Saturday, May 4, 2024 at 12:54 AM | Privacy PolicySite Map © 2024 Elevate Software, Inc. All Rights Reserved Questions or comments ? E-mail us at info@elevatesoft.com |