AppleScript syntax error - function

I trying to output a list of todo items from the Mac app Things using AppleScript.
But I get a syntax error:
Expected expression but found “to”.
Since Things uses the name "to dos" and AppleScript doesn't like this, since to is a reserved keyword. It works without a problem if the repeat code is directly inside the tell statement and not in the function handler.
Is there any way around this?
set output to ""
on getTodos(listName)
repeat with todo in to dos of list listName
set todoName to the name of todo
set output to output & todoName
end repeat
end getTodos
tell application "Things"
getTodos("Inbox")
getTodos("Today")
end tell
Is this even possible to do it like this?
And is there a better way to do this?

Sure, this is readily doable. The problem is that outside the tell application "Things" ... end tell block, AppleScript doesn't know what things would be special inside it, and doesn't even both to look. All you need to do, then, is move the tell block within on getTodos(listName) ... end getTodos:
on getTodos(listName)
tell application "Things"
repeat with todo in to dos of list "Inbox"
set todoName to the name of todo
set output to output & todoName
end repeat
end tell
end getTodos
You may also be able to replace tell with using terms from; I think that should work. Also, you never use listName—did you mean to replace "Inbox" with listName?
You should, however, be able to replace getTodos with the single line
on getTodos(listName)
tell application "Things" to get the name of the to dos of list listName
end getTodos
This sort of shortcut is one of the things AppleScript is good at. Also, note that this new version doesn't modify output, but just returns the list; I'd argue that's a better decision anyway, but you can always do set output to output & ....

I believe the issue is that AppleScript does not know you are trying to use Things-specific terminology in your handler. Try putting the repeat within a using terms from application Things block, like so:
on getTodos(listName)
using terms from application "Things"
repeat with todo in to dos of list "Inbox"
set todoName to the name of todo
set output to output & todoName
end repeat
end using terms from
end getTodos

Related

lua, iterating and calling all same-named-functions of n=3 tiers of tables

Say I have multiple tables in {game} like {bullets}, where {bullets} has multiple tables as found below. How would I iterate through and call all the update functions contained in {game}?
--Below is a simplified example, Assume each table in {bullets} has multiple entries not just update. And that the final code must work in cases like game={bullets,coins,whatever}, each entry being of similar nature to bullets.
game={}
game.bullets={{update=function(self) end,...}, {update=function(self) end,...},...}
for obj in all(game) do
for things in all(obj) do
things:update() end end
--I'm not sure what I"m doing wrong and whether I even need a double for-loop.
--if bullets wasn't embedded in {game} it would just be:
for obj in all(bullets) do
obj:update()
end
I've also tried:
for obj in all(game.bullets) do
obj:update()
end
*correction: this works, the problem I want solved though is to make this work if I have multiple tables like {bullets} in {game}. Thus the first attempt at double iterations which failed. So rather than repeat the above as many times as I have items in {game}, I want to type a single statement.
all() isn't a standard function in Lua. Is that a helper function you found somewhere?
Hard to tell without seeing more examples, or documentation showing how it's used, with expected return values. Seems to be an iterator, similar in nature to pairs(). Possibly something like this:
for key, value in pairs( game ) do
for obj in all( value ) do
obj :update()
end
end

MySQL result to array VB.NET

I am creating a program in VB.NET which uses an online MySQL database to retrieve certain data. I have now succeeded in connecting and getting some basic stuff out of it. Now, what I want to do is that when an user presses a button it has to update the list. What happens is that the stuff that is already in the database also gets resent and so the list just doubles himself, although it adds the new database value.
How can I make sure that it only adds new values to the list, instead of adding all values from the list again? I have read that you can use the Preserve keyword with arrays, though this isn't an array and neither have I figured out how to convert my data into an array.
Private Sub generateList()
DB.writeQuery("SELECT snacks.ID, snacks.naam, snacks.baktijd FROM snacks")
While DB.DR.Read
ListBox1.Items.Add(DB.DR.Item("naam"))
End While
DB.closeConnection()
End Sub
This is the piece of code I use to generate the list, I reuse this code to refresh the list. As you can see, it uses my own written MySQL class. I know it makes an connection so there is nothing wrong with that.
Any help would be appreciated.
What you will want to do is to clear the ListBox before you reload the list. You can do this like so:
ListBox1.Items.Clear()
Then when you reload the list, the items will not be duplicated.
Looks like you need to clear your listbox before adding the items.
ListBox1.Items.Clear()
Try this my friend:
If Not listBox1.Items.Contains(DB.DR.Item("naam")) Then
ListBox1.Items.Add(DB.DR.Item("naam"))
else
'this item already exists.
end if

Why is the BSON Null?

Why is it that when I try and do something very similar to the TMongoWire demo program to load a document, I get a different result? On create of a page, I want to get all the company names and load them (eventually) into a combobox. This is the code I am playing with:
d:=BSON;
q:=TMongoWireQuery.Create(MongoWire);
try
q.Query('mwx1.companies',nil);
while q.Next(d) do
begin
s := BsonToJson(d);
sl.add(d['CompanyName']);
sl.Add(TBSONDocument(d).item['CompanyName'])
end;
finally
q.Free;
end;
At the point where I am assigning the JSON to S, the JSON is fully correct and the CompanyName has data in it. That line was there for testing only. But the next two lines both produce nothing (tried various ways to get the data) because it says that the value is null. If I inspect TBSONDocument(d) it shows all the correct information. So I am baffled as to why it isn't working. Any clues?
It starts out as an empty BSON, but when it's in the loop for the first iteration it contains the BSON of
'{"_id":"ObjectID(\"524547512dcf91c1dc7476cb\")","Email":"2324","CompanyName":"T‌​est 1","Addr1":"fs","Addr2":"ertert","City":"iukuiuiku","State":"uikuiku","Zip":"dsf‌​","Country":"ff","Phone":"fdsd","SalesPerson":"sds","ContactPhone":"sdf","Contact‌​Email":"fsdf","ContactName":"f","DateCreated":"g2","website":"34","SMS":"23","Log‌​o":"23423","Status":"qwqw","Keywords":"3423","Shortcode":"qwqw","ParentID":"asda"‌​}'

PowerBuilder pasting in tabbed data window

I recently started a new job with a company and my first task is to update some quite old software for them.
There is a big back story but basically the software was written in PB8 (around 1997) and no one within the company (including me) has had any experience with PowerBuilder before and as the newbie I have been tasked to update and maintain it until a replacement has been approved and can be developed.
We have the license for PowerBuilder 12.5 so I am using PB12.5 Classic to do everything. The original developer cannot be contacted for support and no documentation exists.
One thing I am trying to understand, that will be a huge help in the future, is how to determine where functions are defined and where variables get their values..
The example I am working on at the moment is the following scenario.
There is a data window with tabs, named tab_detail each tab displays different whatever little orange men are in the tree list.
One of these are called dw_detail which allows pasting of data. None of the other tabs allow pasting of data, but I would like them to. dw_detail has an event rbuttondown() with the following code in it:
Window w_parentwin
If ib_add_mode Or ib_chg_mode Then
w_parentwin = Parent.GetParent().GetParent()
m_dwpaste m_pop_paste
m_pop_paste = CREATE m_dwpaste
m_pop_paste.idw_data = This
If ii_agent_code > 0 And Not IsNull(id_period) And Clipboard() <> "" Then
m_pop_paste.m_popup.m_paste.Enabled = TRUE
Else
m_pop_paste.m_popup.m_paste.Enabled = FALSE
End If
m_pop_paste.m_popup.PopMenu(w_parentwin.PointerX(), w_parentwin.PointerY())
DESTROY(m_pop_paste)
End If
When I add that code to the rbuttondown() event of tab number 2 (dw_adjustment) tab 2 now allows paste when I right click within the dw_adjustment data window but the data gets pasted to the fields within the dw_detail tab not the fields on the dw_adjustment tab.
I have tried debugging and stepping through the code but there are thousands of values in the variable window and without the ability to search I cannot find the variables used above and what their values are or why data gets pasted to the dw_detail tab instead of the dw_adjustment tab when I paste into the dw_adjustment tab.
Basically I am looking for any helpful tips on where to look or what the above is doing and why everything pastes to tab 1 instead of the tab I clicked paste in.
If more detail is needed from code from a different location or more information is needed I am happy to provide it.
As suggested by Seki I found the m_popup when double clicked it came up with wf_pastereturn():
Integer li_idx, li_rows, li_dwrows, li_comm, li_seqno
String ls_approval_type
If tab_detail.tabpage_details.dw_detail.RowCount() > 0 Then
li_idx = 1
li_dwrows = tab_detail.tabpage_details.dw_detail.RowCount()
Do Until li_idx > li_dwrows
ls_approval_type = tab_detail.tabpage_details.dw_detail.Object.approval_type [li_idx]
If IsNull(ls_approval_type) or ls_approval_type = "" Then
tab_detail.tabpage_details.dw_detail.DeleteRow(li_idx)
Else
li_idx++
End If
li_dwrows = tab_detail.tabpage_details.dw_detail.RowCount()
Loop
End If
If li_dwrows > 0 Then
li_seqno = Long(tab_detail.tabpage_details.dw_detail.Object.seq_no [li_dwrows])
End If
li_seqno += 10
If Clipboard() <> "" Then
If tab_detail.tabpage_details.dw_detail.ImportClipboard(1, li_rows, 1, 4, 3) <= 0 Then
MessageBox("Invalid Data", "Unable to paste!", StopSign!)
Return -1
End If
li_rows = tab_detail.tabpage_details.dw_detail.RowCount()
li_dwrows++
For li_idx = li_dwrows To li_rows
tab_detail.tabpage_details.dw_detail.Object.approval_type [li_idx] = trim(tab_detail.tabpage_details.dw_detail.Object.approval_type [li_idx])
tab_detail.tabpage_details.dw_detail.Object.approval_no [li_idx] = trim(tab_detail.tabpage_details.dw_detail.Object.approval_no [li_idx])
tab_detail.tabpage_details.dw_detail.Object.agent_code [li_idx] = ii_agent_code
tab_detail.tabpage_details.dw_detail.Object.period [li_idx] = id_period
li_comm = f_new_commission(Long(tab_detail.tabpage_details.dw_detail.Object.value_of_work[li_idx]), id_period)
tab_detail.tabpage_details.dw_detail.Object.levy_payable[li_idx]= &
inv_rate.of_CalculateLevyPayable (Long(tab_detail.tabpage_details.dw_detail.Object.value_of_work[li_idx]), id_period)
tab_detail.tabpage_details.dw_detail.Object.comm_deductable [li_idx] = li_comm
tab_detail.tabpage_details.dw_detail.Object.commission [li_idx] = li_comm
tab_detail.tabpage_details.dw_detail.Object.seq_no [li_idx] = li_seqno
li_seqno += 10
tab_detail.tabpage_details.dw_detail.Object.agent_return_detail_create_date[li_idx] = Today()
tab_detail.tabpage_details.dw_detail.Object.agent_return_detail_create_user[li_idx] = SQLCA.Logid
Next
Clipboard("")
Return 0
Else
Return -1
End If
I modified the function to use the windows SelectedTab property. Data will now paste into the tab but in the wrong input fields. I looked further and the data columns for the ImportClipboard function do not line up.
How is the best way to change the order of the selected database columns?
Here is a screenshot of what I mean by tabs:
So within the main program window, there are the above tabs, within each tab (where the input fields are) there is a data window labelled with the dw_ prefix.
Thanks heaps for your help.
I think first you should do some short tutorials. Please check out these:
PowerBuilder Classic 12/12.5 guide/tutorials
These are short and useful.
On the other side you are able to select specific variables in your own "watch variable" list, so you do not have to search over the several variables. You can right click on the variable name and do a Quickwatch or you can Insert the variable name in the Watch window.
Br. Gábor
The action with a contextual menu is in 2 times :
handle the mouse right click to display a contextual menu
perform an action among the one or several actions provided by the popup menu
You shown the pbscript that is displaying the menu with PopMenu() if there is something in the clipboard (Clipboard() <> "") and maybe you did not noticed that the pasting action is somewhere else.
Look in m_popup: there must be some code inside that may be hard-coded to paste in dw_detail. If so, maybe that you could store in the window instance variables a reference to the currently processed dw for the contextual menu.
Something like :
datawindow idw_current in the instance variables
then in the rbuttondown() event idw_current = this (this being the datawindow the rbuttondown() event belongs to)
and finally in the menu reuse the id_current instead of a hardcoded dw_detail
Concerning your question about where the variables are modified: what you can do is searching the variables by their name (right click on the target or a single pbl or object then 'search'), and put a breakpoint on the lines where they are affected. If you run in debug mode (CtrlDCtrlT instead of CtrlR) you will be able to trace when a variable is modified.
Paste Problem
Pass 1
It's hard to tell for sure, but I'd look at the code of m_dwpaste.m_popup.m_paste.Clicked. The worse case scenario is that dw_detail is hard coded into that script; the slightly better case is that it has a more flexible routine in there, but somehow dw_adjustment doesn't fit into that algorithm.
Pass 2
With the new information, we can see that the code of wf_pastereturn() (I'm not sure how you got to this script, but this looks like the culprit) is not simply pasting, but doing a lot more that involves specific fields. In fact, it's not just pasting, it's importing the data, which means that it's assuming the contents of the clipboard are not only in a specific format, but match the data set of the DataWindow (see the Columns pane in the DW painter, and be careful not to confuse the data set part of the DataWindow with the UI part). The question is, do you want:
"Pasting" like copying text from Notepad into a browser form; just putting text into the current field?
"Pasting" exactly like the other DataWindow, including assumptions that all the same columns mentioned in the script are in both DataWindows?
"Pasting" something like this script, but customized for the data set in the new DataWindow?
These all require somewhat different solutions, combined with the differences I asked about in my comment about tabs vs. DataWindows.
Finding Stuff
I'm going to give an unapologetically biased point of view, because I'm the author of a tool that, among other things, helps you search PowerBuilder code called PBL Peeper.
If you're looking at code in the Browse tab, and you want to see other mentions of the variable, you can select it, right click, and either
search forward or back within the script
search for the object name in the tree on the left (it'll make more sense when you see it)
search either the rest of the object or the rest of the application
Finding where a variable is assigned is more difficult than it sounds, because of the multiple syntaxes that could be involved.
// assigns a value on instantiation
int i = 1
// assigns a value when executed
i = 1
// does not assign a value
IF i = 1 THEN
// assigns a value possibly if the parameter is passed by reference (kind of like a pointer to the variable)
f_foo (i)
Finding the setting of a variable can be helped by understanding variable scope. If the variable is local, you only need to search the script. If the scope is instance or shared, you need to search the object (as above, pretty easy) and its descendants (easy to go to a given descendant with an RMB on the treeview, harder to search on a set of descendants). If the scope is global, you want to search the entire app.
Finding where a selected function is declared is possible, but you need to know a little secret (or RTFM). The Find on the RMB menu uses the parameters from the Find page, so you need to set Portion Type to All, not just Scripts, to find where functions are declared. Alternatively, you can use the Lists / Scripts pages and find the script using the functions on that page (Find, QuickFind, Filter, etc...).
The tool has a plethora of functionalities that let you find, filter and sift through code to get at what you're after. The above is just a quick introduction.
Good luck,
Terry.

Use a value from a combo/text box in a file path string

I have a form that I intend to allow users to browse powerpoint presentations through, because there are a lot of different briefs for metrics, which is what I use this database for. So, I already know how to set up everything, just got one little hang up.
If I place a combo box on the form to select from a list of different presentation, can I use that in the file path string (that I have to use to pull the ppt into theobject frame in access.
example:
"C:\Users\Justin\Desktop\" & cmbTitle & ".ppt"
I tried it and it gives me the error message variable not defined. I never defined a control before on in these things, would it be as a string?
I realize that the exact file path much match the entered value. Access 2000-2003/XP
Thanks as always guys!
You need to refer to the field as Me.cmbTitle. As it is written, it looks like you're calling the variable cmbTitle which doesn't exist.
Is the value of cmbTitle some ID/Integer field or is it the actual string value? You may want to use the immediate window to check this. Also, make sure the value of cmbTitle doesn't have any backslashes or spaces (That may require quotes?).
I'm somewhat confused as to what you're trying to do. I will write my answer assuming:
you have a form in an Access database.
on that form is combo box that lists the PowerPoint presentations your users are working with.
the bound column of the combo box lists the filename (without path) of each PPT file.
when the user selects a filename from the combo box, you want to display it in an unbound OLE object frame.
The code for that, assuming the list of PPT files is called cmbTitle, would be in the combo box's AfterUpdate event and would look like this:
Private Sub cmbTitle_AfterUpdate()
Dim strPresentation As String
If IsNull(Me!cmbTitle) Then Exit Sub
strPresentation = "C:\Users\Justin\Desktop\" & Me!cmbTitle & ".ppt"
Me!olePPT.SourceDoc = strPresentation
End Sub
Now, I can't get a test unbound OLE object frame to work with this, but it seems to me to be the right way to do it.
My suspicion is that you're either attempting to set the wrong property, or you've defined your OLE frame wrongly, but I can't offer any more advice on that without knowing more about what you're actually attempting to do, and exactly what line of code is causing the error.