Here's my code:
Set item=doc.GetFirstItem("Path_1")
Set item1=doc.GetFirstItem("Path") ' Path is a multiple value field.
filenames = ws.OpenFileDialog(True, "Select",, "")
If Not(Isempty(filenames)) Then
Forall filename In filenames
item1.AppendToTextList(filename) 'Path contains all the paths selected.
End Forall
End If
What I want to do is to add the filepath selected from the OpenDialog into Path_1, but not all of them. Eg: Path1 selected => Path contains Path1. After this, Path2 is selected => Path contains Path2. ( overwrite ... )
First of all: The first parameter of "OpenFileDialog" stands for multiple selection. If you just want to select ONE file, then just set this to false.
filenames will still be an array, but just with one entry.
Second: If you want to set ONE value to an item, then use replaceitemvalue of NotesDocument or just the value property of the item:
Replace:
Forall filename In filenames
item.AppendToTextList(filename) 'Path contains all the paths selected.
End Forall
with:
item.values = filenames(0)
or:
doc.ReplaceItemValue( "Path", filenames(0) )
or:
item.text = filenames(0)
And some other thing:
First of all: Use Option declare in ALL of your code, it makes life much easier.
Then: You define item1 twice: First it takes the item "Path_1" and directly after that you assign it the item "Path"... That makes no sense as you do not even use item, when it is assigned to "Path_1"...
Just to have a complete solution here: For me the code would look like:
Dim ws as New NotesUIWorkspace
Dim doc as NotesDocument
Dim itemPath as NotesItem
Dim varFiles as Variant
Set doc = .... 'somehow set the doc
Set itemPath = doc.GetFirstItem( "Path" )
varFiles = ws.OpenFileDialog(False, "Select",, "")
If not isempty( varFiles ) then
'- Just Write the LAST value into Path_1
call doc.ReplaceItemValue( "Path_1" , varFiles(0) )
'- Append the selected value to the path "History"
itemPath.AppendToTextList( varFiles(0) )
End If
Related
How can I make the 2 "print" give me true?
Code:
Config = {}
Config.option1.general = true
Config.option2.general = false
print(Config.option1.general)
print('Config.'..'option1'..'.general')
Output:
true
Config.option1.general
Excuse me for my ignorance
The objective was to create a function to which you give the option and execute a code with the variables of the corresponding list.
Just create a function that takes as input an option string, and use the string as a key into the Config table:
function getOption (opt)
return Config[opt].general
end
Then you can use the returned value however you like:
> getOption('option1')
true
> print(getOption('option1'))
true
> if (getOption('option1')) then print 'Yay!' else print 'Aw...' end
Yay!
If you want to live dangerously, you can use load to run a chunk of code from a string. Using this feature with user input is begging for security problems, though.
Just write a function that takes a string specifying the option, and use that input to fashion a string representing the chunk. The load function returns a function that has the chunk as its body, so you will need to call that returned function to get the result from the chunk:
function getOption (opt)
local cmd = 'Config.' .. opt .. '.general'
return load('return ' .. cmd)()
end
With getOption('option1'), the cmd string becomes 'Config.option1.general', and this is concatenated with 'return ' to create the chunk 'return Config.option1.general' which is passed to load. The statement load('return Config.option1.general')() calls the function returned by load, and the returned value is returned again from the getOption function.
Sample interaction:
> getOption('option1')
true
> getOption('option2')
false
the first print is collecting a variable and therefore displaying the value of this variable
the second print is already collecting a STRING. A string is a set of characters, they represent only text, and therefore that text will be displayed
for example, imagine that we have a variable test = true
if you do print(test), the value of the variable will be displayed, that is, true. Now, if you get print("test"), the "" means that we are talking about a text "test", not the variable test, so test will be displayed instead of true.
Note that in the second print, 2 dots .. are used, this is called CONCATENATION, it is when we join two or more strings, that is, two or more texts in one
For this reason there is no way you print true on the second print, because you are collecting a STRING with the name of the variable, and not the variable itself
I'm making a program in VB6, and I can't properly loop through a String dictionary.
I've tried both ways of accesssing a value in the collection. Collection(Key), and Collection.Item(Key).
Dim line As Variant
Dim thismsg As New Collection
Dim thissection As String
For Each line In Split(NetRcv, vbLf)
If Left(line, 3) = "BLK" Then
thissection = Right(line, Len(line) - 3)
MsgBox thissection
GoTo nctlrParseLoopNext
End If
If Left(line, 3) = "BND" Then
Exit For
End If
Dim key, value As String
key = Left(line, InStr(line, " "))
value = Right(line, InStr(line, " "))
thismsg.Add key, value
nctlrParseLoopNext:
Next line
Dim member As Variant
For Each member In thismsg
MsgBox member
MsgBox thismsg(member)
Next member
The string in NetRcv is the following:
BLK modeswitch
mode codeslave
BND
I expect to see this sequence of MsgBoxes ...
modeswitch
mode
codeslave
... with possibly trailing spaces somewhere.
I see the first two, and then it errors with
Run-time error '5':
Invalid procedure call or argument
I don't understand why this error occurs.
member is the key, correct?
If it is, then there's no reason this error should pop up.
For one thing, you have inverted the value and key. This:
thismsg.Add key, value
should be this:
thismsg.Add value, key
See here for the docos on the Add method
https://learn.microsoft.com/en-us/office/vba/language/reference/user-interface-help/add-method-visual-basic-for-applications
Why this works:
def m = [[1,11], [2,22], [3,33]]
println(m.collectEntries())
output: [1:11, 2:22, 3:33]
But this doesn't work:
def m = [[Name:sub, Value:23234], [Name:zoneinfo, Value:Europe/London]]
println(m.collectEntries())
output:
groovy.lang.MissingPropertyException: No such property: sub for class
I want to process that map so that I get a list of key value pairs like this:
["Name:sub" :"Value:23234", "Name:zoneinfo": "Value:Europe/London"]
where Name:sub is the key and Value:23234 is the value.
Reference https://stackoverflow.com/a/34899177/9992516
In the second example sub and zoneinfo are being read as variable names, not strings, and you need to quote them.
def m = [[Name:'sub', Value:23234], [Name:'zoneinfo', Value:'Europe/London']]
println m.collectEntries{ ["Name:${it.Name}", "Value:${it.Value}"] }
It cannot find sub field in your class, probably you want to have a string "sub"?
Basically, map entry can be declared in two ways:
Name: 'sub'
and
'Name': 'sub'
For the key it is assumed that is is a String, even if it is not wrapped by quotes.
But for the value it is mandatory to wrap in quotes. Otherwise, it is treated as a variable (or field)
Given your desired results:
["Name:sub" :"Value:23234", "Name:zoneinfo": "Value:Europe/London"]
What you actually need to do is quote the entire item in each pair:
def m = [["Name:sub", "Value:23234"], ["Name:zoneinfo", "Value:Europe/London"]]
I am having a problem with variables inside tables. this is essential since I use tables as configuration for my program.
so I have tested the following code that works:
> x = "X"
> t = {["ref"]="table with value: "..x}
> print(t["ref"])
table with value: X
> x = "Y"
> t = {["ref"]="table with value: "..x}
> print(t["ref"])
table with value: Y
it however doesn't work without the second > t = ["ref"]="table with value: "..x
now I went to implement this into my main program witch consists of two files, one witch returns the configuration table. And one file with all the functions and stuff. it looks as following
FILE A (main.lua):
testString = "test1"
print(testString)
local CONFIG = require'config'
print(CONIFG[1].test)
testString = "test2"
print(testString)
local CONFIG = require'config'
print(CONIFG[1].test)
FILE B (config.lua):
local CONFIG = {
{["test"]=[[this is a test: ]]..testString}
}
return CONFIG
now when i run file A (a.k.a. main.lua) i get the following output:
test1
this is a test: test1
test2
this is a test: test1
i can't figure out what i am doing wrong here.. i thought it had something to do with that it was a single string so i made testString a table but that gave me the same result...
(that title really seems scary.. sorry)
require, by design, caches the return value. So if you call require with the same string, it will not execute the script again. It will simply return the previously returned value.
require is for loading modules. And modules should not change their return values based on other global state.
The function you're probably looking for is dofile. This will always load and execute the file (but it has none of the path searching properties of require). Alternatively, you can use loadfile to load the file as a function, then execute that function to regenerate the table whenever you want.
Also:
I am having a problem with variables inside tables.
There are no "variables inside tables". Or at least not the way you mean. Expecting a change to a variable to affect some other value is like expecting this:
a = 5
b = a + 5
a = 10
assert(b == 15, "This will never be true.")
When an expression (whether a + 5 or "table with value: " .. x) is evaluated, it results in a value. The resulting value is in no way dependent on any value or variable from the expression that generated it.
That's why you had to regenerate the value; because values don't change just because some variable changes.
After I did a query in openoffice-base over a customized form I want to transfer a selected set of data into a template openoffice-calc table. I know I can access the data set in openoffice-calc via pressing the Data Source (F4) button but then I only get access over the query. The best solution would be after the database query over a form a button event is required to open a openoffice-calc table from the template and insert the data from the data set.
First go to Tools -> Macros -> Organize Macros -> LibreOffice Basic and add this code. Change the path of the template file.
Sub Copy_Record_To_Calc(oEvent)
Dim oForm
Dim templatePath As String
Dim oServiceManager As Object, oDesktop As Object
Dim oFileProperties As Object
Dim oDoc As Object, oSheet As Object, oCell As Object
Dim column As Integer
oForm = oEvent.Source.getModel().getParent()
If oForm.isAfterLast() Then
Print "Hey, you are after the last element."
Exit Sub
ElseIf oForm.isBeforeFirst() Then
Print "Hey, you are before the first element."
Exit Sub
End If
templatePath = "file:///C:/Users/JimStandard/Desktop/Untitled 2.ots"
Set oServiceManager = CreateObject("com.sun.star.ServiceManager")
Set oDesktop = oServiceManager.createInstance("com.sun.star.frame.Desktop")
Set oFileProperties(0) = new com.sun.star.beans.PropertyValue
oFileProperties(0).Name = "AsTemplate"
oFileProperties(0).Value = True
Set oDoc = oDesktop.loadComponentFromURL( _
templatePath, "_blank", 0, Array(oFileProperties))
oSheet = oDoc.Sheets(0)
For column = 1 to 2
oCell = oSheet.getCellByPosition(column - 1, 0)
oCell.String = oForm.getString(column)
Next column
End Sub
Then in form design mode, right-click on the button and choose Control. In the Events tab, click the three dots next to Execute action. Click Macro... and find the Copy_Record_To_Calc macro that you added.
Now turn design mode off. Go to a record and click the button. It will open the Calc template and copy the first two columns of the current record into column A and B of the spreadsheet.
See also:
Section 4.2.1 of Andrew Pitonyak's Base Macros (PDF)
ResultSet documentation
This thread gives an example of using a Calc template.