How to change datasource of datawindow from procedure to query without changing source? - datasource

PowerBuilder 12.5
I do not want to edit the datawindow object source code and i want to change datasource of the datawindow where i used a stored procedure. i want to use a different stored procedure or query. How to do that without editing the source of datawindow?

If I was in your case I would create another datawindow with the other stored procedure call, then I would change the dataobject between them with if-then-else.
If you need to have strictly the same dataobject then I would tried something with retrieval args and send as retrieval a value that would distinguish the two different options, then you can use IF-THEN-ELSE inside the datasource.
IF :al_arg = 1 THEN
call procedure1;
ELSIF :al_arg = 2 THEN
call procedure2;
ELSE
//something else
END IF;
Hope it helped!

I would also create a new datawindow with as data source your procedure. Then to use it, use the sharedata() function.
More specifically, if you have a datawidnows control dw_1 holding your 'old' datawindow, create a new (possibly hidden) control dw_new and use the new dataobject in it. Alternatively, you could use a datastore.
Then code:
dw_1.reset // To make sure everything has been flushed
dw_new.retrieve()
dw_new.sharedata(dw_1)
The abolute condition for this to work is to have exactly the same buffer ie the same fields with the same definition.

Related

How to use Form Controls in Modules

In my modules, I want to use my controls from my form. For example: I want to set focus on a textbox after a certain Sub.
My current solution is to make a subroutine to set all controls in a public variable (see below).
My questions:
What is the best practice? How do people usually do this?
When should I call my subroutine? (is it the first call in the FORM_LOAD sub?)
Public TBnr As TextBox
Public Sub controlsInitieren()
Set TBnr = Forms("frm_TreeView_Example").pstNr
End Sub
Well, as a general rule, while many platforms seperate out the UI part and the code part? Well, Access is quite much a different approach - it is standard fair to place the required code inside of the form "class" (all forms in Access are a "class", and you can even have muliple instances of the SAME form open more then one time).
So, in general, your code should be in the forms code (class) module.
However, you could and call a external routine.
So in the form, you could call your above routine like this:
Call MySetFocus(me, "NameOfControlToSetFocusTo")
And your sub would look like this:
Sub MySetFocus(f as form, sCtrl as string)
f(sCtrl).SetFocus
End Sub
However, as noted, the amount of code above is more code then simply in the forms code module going:
me.ControlName.SetFocus
However, while the above is a less then ideal example, passing the form "instance" (me) to a external sub or function allows you to referance any property or method or feature that exists in the form in an external routine.
So in place of say
me("LastName") = "Zoo"
In the above sample routine, you would and could go;
f("LastName") = "Zoo"
So any place you would and could use "me" in the form, you can use the form instance you passed from the form. As noted, it is a good idea to use "me", since as I noted, Access does allow multiple copies of the form to be opened at the same time - and thus your code can't distinguish between what form instance you are using unless you pass the current "in context" form. So like in JavaScript, using "this" ?
In access that current instance of the class object is "me", and you are free to pass that instance to any sub or function you want as per above.
The best practice is to use only procedures inside the form code. In such a case you refer to a text box control in this way: Me.Textbox1.SetFocus. If you want to set some controls properties during the form loading, you can do that in the frm_TreeView_Example_Initialize event;
They usually do it in the way I described at item 1;
If you want to use such a strange/unusual way you can do it calling the subroutine whenever you want. But, in order to set a specific property value of the form frm_TreeView_Example controls you can simply use frm_TreeView_Example.TextBox1.SetFocus. You can use this way of setting in a module procedure, even before the form has been shown. You can simply show it in that procedure code using at the end: frm_TreeView_Example.Show;

GridView does not update DataTable

I am using a DevExpress XtraGrid/View for windows forms. The datasource of the grid is a binding source, which is connected to a dataset. My problem is, this table adapter does not update the datatable. I can insert new rows without problems, but I can't update. No error message is thrown; when I save changes, the row value just reverts. This happens for every column in the row. Here is my code for saving and then reloading data:
' Class variable
Private _invoiceDetailsAdapter As dsInvoiceDetailsTableAdapters.inv_InvoiceDetailsTableAdapter = New dsInvoiceDetailsTableAdapters.inv_InvoiceDetailsTableAdapter()
'Save Data
InvInvoiceLineBindingSource.EndEdit()
_invoiceDetailsAdapter.Update(DsInvoiceDetails.inv_InvoiceDetails)
'Load
DsInvoiceDetails.inv_InvoiceDetails.Clear()
If Me._invoiceId > 0 Then
_invoiceDetailsAdapter.Fill(DsInvoiceDetails.inv_InvoiceDetails, _invoiceId)
InvInvoiceLineBindingSource.Sort = "LineNum"
End If
I've figured out that it must be the dataset itself, because I've tried using a regular DataGridView with the dataset, to no avail. I generated the dataset through the wizard and had to add ColumnName and SourceColumn properties in the parameters for Insert & Update. The parameters for Insert & Update look identical as far as properties are concerned.
I've also tried creating new datasets, datatables, binding sources and tableadapters. I've even tried a DataAdapter but there was no difference. I have literally spent 2 weeks now looking through the properties and debugging, trying to find a cause.
Can someone please offer some advice?
The problem was DevExpress' XtraGrid functionality.
The XtraGrid does not immediately save an edit value to the linked dataset. The modified row is usually posted to the data object when focus is moved to another grid row. You can programmatically force the update by calling the UpdateCurrentRow method. In your case you should only call the CloseEditor and UpdateCurrentRow methods before updating the dataset via the DB adapter object.
So if a user only updates only one row, those changes go nowhere. Read on for a code snippet...
http://www.devexpress.com/Support/Center/Question/Details/A327

How to load code before on form load

I have some code I need to load in before I want the code to run (I want to create a table), I tried 'Onload' but this is not soon enough, basically I'm looking for something just like OnInit() where I can load all I need before anything actually occurs. My problem is that it's checking for the table way to early (Because it hasn't been created yet)
http://gyazo.com/c731783b9b2a01dcaf93f92a170f61ba
So really I just need some help with calling code before the actual onLoad event is called.
THanks
Is OnOpen event suitable?
And you can have empty RecordSource in form and set it after you have created table.
1. open form in design view
2. copy RecordSource
3. in you event(onOped or onLoad) put after table creation code
Me.RecordSource = "COPY'ed recordsource"

creating fields in lotus notes document?

I am trying to export items from my access database into lotus notes. The document I am trying to export to is a stationary, and has all the data written into it, I just need to somehow mark placeholders and then update the values. I have read the documentation and it appears I will need to address fields and then call a method to replace the text like so:
'where body is the field and the following string is what to replace field with
Call doc.ReplaceItemValue("body", "REPLACE BODY")
To be clear, my entire code looks like:
Set session = CreateObject("Notes.NotesSession")
Set maildb = session.GetDatabase("server", "mail\box.nsf")
Set View = maildb.GetView("Stationery")
Set entries = View.AllEntries
Set entry = entries.GetFirstEntry
Set doc = entry.Document
Call doc.ReplaceItemValue("Subject", "Report - " & Date)
'add code here
Call doc.send(False, "person.to.receive#thisemail.com")
End Sub
I have noticed that while perusing documentation, there seems to be an ability to create fields, and then address those fields to update values. So for example, if I have a field named $COST, then one could do:
Call doc.ReplaceItemValue("$COST", "The cost is $3000")
And that field should be updated to reflect the value I passed through the method. My big problem is, even looking through documentation, I cannot figure out where I need to go to add in my custom fields. It seems that the documentation assumes that you know how to create these fields and just address them. Or am I only supposed to create these fields programatically and then fill in the data? My client is Lotus Notes 8. Thanks!
Yes, that is the cool thing about IBM Lotus Notes databases: you can put items (=fields) in a Notes document without a prior definition of fields.
If you create items in a document with doc.ReplaceItemValue() and save or send the document then the items are just there. You can check the items when you open the property box for a selected document. All items are listed on document properties' second tab.
Another question is of course to define fields in a form so that the created items are visible to user without looking at document properties box. Open database in Designer and put the fields in right position and size to form.
Your question and comments telling that you want to create a document, fill it with data and send it to users.
If all users have access to your Notes server then you can create that document in your existing database and send just a link mail to users. This way you can create a good looking form and position all your data fields. Users will access the document in database through link.
An alternative is to create an nice looking HTML file, attach it to the mail and send it.
In this case you would add this code to your example at 'add code here:
Call doc.RemoveItem("Body")
Set rtitem = doc.CreateRichTextItem( "Body" )
Call rtitem.AppendText("your mail text")
Call rtitem.EmbedObject(EMBED_ATTACHMENT, "", "report.html")
Based on the comment thread on #Knut Herrmann's answer, I believe that the solution you really want involves using "stored form". The first argument to the NotesDocument.Send() method is a boolean that specifies whether you want to store the form or not.
Normally, you would use Domino Designer to create a stored form. You would not need Designer rights to anyone's mailbox. You would just need to create an empty database of your own, and put a form into it. You woould change your code to open that database and create the document in there instead of in a mailbox database as you are doing now. (One of the other cool things about Notes is that you don't actually have to be working in a mailbox database in order to mail a document. You can mail any document from any database, as long as you put the approporiate fields into it.)
There is also a way to do this without Domino Designer, and you could even dynamically generate the form with truly custom fields that your code only discovers as it runs. You could do this with DXL, which is an XML format for describing Lotus Notes objects, including forms. You would just need some sample DXL to work from. Preferably that should be of an empty database that contains a simple form that is set up more or less in the layout that you would want, though again you would need Domino Designer for that. You could just use the same mailbox database that your code is currently using, but that will leave you with a lot of extra stuff in the DXL that doesn't need to be there; and given that you're not all that familiar with Notes, it would likely be difficult for you to navigate through it all to find what you need.
Either way, though, you could use the NotesDXLExporter class to generate the DXL file. Your code could manipulate the DXL, adding/changing elements as needed (following the pattern that you see in sample, of course), and they you could use NotesDXLImporter to create the database that your code will actually use to create the document in and mail the message with the stored form.

Get Values from Listbox for if functions

Hey guys very new here.
Have a listbox that gets account names from a specific game server using this command line
Dim apikeyinfo As APIKeyInfo = api.getApiKeyInfo()
lstbxCharacters.DataSource = apikeyinfo.Characters
this code gets all the characters in a single account by displaying it in a listbox.
Now i would like to reference a character from the lisbox but not sure how
Any method such as Listbox.Get to get the value and compare it with something else?
Thanks
you can try something like
lstbxCharacters.SelectedItem
Update
To read the data from the listbox I think there are multiple ways (Assuming that it is readable).
-> Usually listbox display strings, so it should work to read to a string variable
Dim a_string as Strin = lstbxCharacters.SelectedItem
also you may like to add a small check before, assuring that an Item is currently selected:
If lstbxCharacters.SelectedIndex < 0 then return
This jumps out of current sub if no item is selected
And finally, to read the first entry, you can also do it this way:
a_string = lstbxCharacters.Items(0)
if it returns objects, then instead of accessing the object directly, it may work to do
a_string = lstbxCharacters.Items(0).ToString
(most objects allow a .ToString() Function )
Here two ideas for different solutions:
As a user commented, you could access the DataSource directly + the information which listIndex was selected. But if you do so, then maybe it is more easy (if you need to access it anyways, to go with solution 2)
Create a variable of type list(Of some_object) and fill it with the data from the datasource. It will take some time to do this, but if you define for the class some_object a function ToString, then you can fill all objects directly to the lstbxCharacters, and access them without any worries, by doing CType(lstbxCharacters.SelectedItem, some_object)
Update 2
If with reference you mean to access further information from the datasource, then you need to build some kind of query, or set the content of the listbox in relation to another control that shows the database content (in that way the listbox lstbxCharacters would act like a filter)