While building a for each loop which connects to outlook and searches for specific subject line(s) I encountered the iterator working correctly upon entry of the loop (i.e. emails were found and stored in the flow variable) for the 2nd searchterm it empties the entire array and starts anew. Upon not finding the specified the flow stops and reports back not having found anything.
I've tried looking at making the storage append in stead of overwrite but can not find anything to do so.
Also have tried to move the data off to a file for a short while but this gets overwritten as well.
Is there a way to make the array append in stead of getting overwritten?
Outlook.Launch Instance=> OutlookInstance
ON ERROR REPEAT 1 TIMES WAIT 2
END
LOOP FOREACH QM_loop IN Query_mails
Outlook.RetrieveEmailMessages.RetrieveEmails Instance: OutlookInstance Account: Support_Account_2_O365 MailFolder: $'''Postvak In''' EmailsToRetrieve: Outlook.RetrieveMessagesMode.All MarkAsRead: False SubjectContains: QM_loop Messages=> RetrievedEmails
END
Display.ShowMessageDialog.ShowMessageWithTimeout Title: $'''Berichten tellen''' Message: $'''%RetrievedEmails.Count% berichten gevonden met de term: \"%QM_loop%\".''' Icon: Display.Icon.Information Buttons: Display.Buttons.OK DefaultButton: Display.DefaultButton.Button1 IsTopMost: True Timeout: 3 ButtonPressed=> ButtonPressed
Related
I've been trying to build a form to create and delete Revit print Sets.
I've 2 main issues:
1) I'm able to create a print set but I cannot access its content unless I restart the Form. I get the errors below (depending if I'm defining the view_set variable or not)
List_object_has_no_attribute_Views
Local_variable_referenced_before_assignment
This is the code of the function to display the sheets of the selected Print Set
def DisplaySheetsInSet (self, sender, args):
self.curItem = CurrentSetsListBox.SelectedItem
PrintSetForm_Load
try:
view_set=[]
for i in PrintSetForm.ViewSets:
if i.Name == str(self.curItem):
view_set = i
else:
continue
Sheets=[sheet.Name for sheet in view_set.Views]
SheetsLb.BeginUpdate()
SheetsLb.Items.Clear()
for sheet in Sheets:
SheetsLb.Items.Add(sheet)
SheetsLb.EndUpdate()
except Exception as e:
popup (str(e)
2) I'm able to delete print sets once. If I try do delete another one I get the following error and I need to restart the form ( code for the function that deletes the print sets shown below)
The_referenced_object_is_not_valid
def DelPrintSet(self, sender, args):
self.curItem = CurrentSetsListBox.SelectedItems
t = Transaction (doc, 'Delete printset')
t.Start()
for viewset in PrintSetForm.ViewSets:
if viewset.Name in [str(item) for item in self.curItem]:
doc.Delete(viewset.Id)
doc.Regenerate()
else:
continue
self.Refresh()
UpdateSetNames(CurrentSetsListBox)
t.Commit()
I've tried to build a function to restart/refresh the Form but it doesn't work (code below):
global PrintSetForm_Load
def PrintSetForm_Load(self, sender):
Application.Exit()
Application.Restart()
#self.Refresh()
#self.ResetBindings()
#self.ActiveForm.Close()
sd = PrintSetForm()
sd.ShowDialog()
This gif shows the form in action:
Manage Print Sets
Any ideas or suggestions?
Thank you.
3) If I try to populate the SheetsLb with a DataSource, just the first set clicked is shown.
Sheets=[sheet.Name for sheet in view_set.Views]
SheetNumber=[sheet.get_Parameter(BuiltInParameter.SHEET_NUMBER).AsString() for sheet in view_set.Views]
SheetsLb.BeginUpdate()
SheetsLb.DataSource = None
SheetsLb.Items.Clear()
UpdatedList=[]
for number,name in zip(SheetNumber,Sheets):
UpdatedList.append(number+" - "+ name + " [ ] ")
SheetsLb.DataSource=UpdatedList
SheetsLb.EndUpdate()
1) See if this works:
It would be worth checking that there is something selected in self.viewSetsLb. Ive added a check to the code below
The view_set variable could be initialised as a boolean instead of a list
Using break in the for loop keeps things a little snappier
Ive used the more pythonic for view in PrintSetForm.viewSets rather than for i in PrintSetForm.viewSets - keeping it nice and clear
This code works for me:
self.curItem = self.viewSetsLb.SelectedItem
if not self.viewSetsLb.SelectedItem:
print 'No Printset selected!'
return
view_set = False
for view in PrintSetForm.viewSets:
if view.Name == str(self.curItem):
view_set = view
break
else:
continue
Sheets=[sheet.Name for sheet in view_set.Views]
self.sheetsLb.BeginUpdate()
self.sheetsLb.Items.Clear()
for sheet in Sheets:
self.sheetsLb.Items.Add(sheet)
self.sheetsLb.EndUpdate()
2) Its because the data in your PrintSetForm.ViewSets list is out of date. Every time you change something (ie delete a viewset), repopulate this list:
PrintSetForm.ViewSets = FilteredElementCollector(doc).OfClass(ViewSheetSet).ToElements()
Also, you shouldnt need to build a refresh button, perhaps have a class function that repopulates the Printset list and ListBox, and clears the Sheet ListBox that you call after every action?
Sounds like youre having fun mate!
It sounds as if you have an issue with the scoping and lifetime of variables. For instance, some variables may have a lifetime limited to the form display, and therefore cannot be accessed after the form is closed. You could change the lifetime of these variables, e.g., by making them static class variables instead of local instance variables. I suggest you read up on .net static class variable scope.
I'm trying use slots on my dialog nodes on Watson conversation but seems that is not properly useful if you want to play with array of literal. I've an entity "#email" that is a pattern so I must use .literal if I want to store the "real value", that is sent by the user, on a context variable. Trouble starts when I try to use #entity.values to store all values that are sent by the user. Actually is not possible to store an array of literals and I'm stuck at this point.
Anyone developed a workaround for this?
The literal is a method, not an attribute. The entities contains a location field, which you can programatically use at the application layer to parse the input text.
If you want to pull them out in conversation, you can use a counter to walk through the entities.
For example:
In your slot node "Then respond with" add the following context bit.
"context": {
"counter": "<? entities.size() ?>",
"literals": ""
},
Next create three child nodes.
Node 1: Create a dummy node, set condition to true. Have it jump to the second node.
Node 2: For the second node, set the condition to $counter > 0 and add the following code to the JSON section.
"context": {
"counter": "<? $counter - 1 ?>",
"literals": "<? entities[$counter].literal + ',' + $literals ?>"
},
Have it jump back to Node 1. The reason for this is Conversation will not allow you to jump to the same node.
Node 3: Have it output the answer. For example: Literal Values: $literals
Here is a sample workspace.
https://pastebin.com/xwgnLq9n
Warning
Watson Conversation has a built in endless loop detection. If a node is hit 50 times in one request, it will throw the following error:
Detected recursion when processing the node with id
[node_20_1513835954092]. This node has been already processed [50] times
in this execution step
At which point the node will fail and you will get no result back. So if you expect more than 50 entities then you need to do this at the application layer.
I want to have a scenarios of 3 runs in GAMS, where I also want to save each of the 3 randomly selected elements of the set "codes" into a .gdx file, without each entry being overwritten by the next randomly generated output in the loop. How can I prevent this overwritting such that I am able to save each randomly generated output in the loop, in one single output.gdx file? The following is my code so far:
SET
codes /aaa, aab, aac, aad, aae, aaf, aag, aah, aaj, aak, aal/
selected(codes);
$gdxout outputs
loop((1,3),
randnumber = uniformint(1,11);
selected(codes)=ord(codes)=randnumber;
execute_unload 'output.gdx',selected;
display selected;
);
$gdxout
The result of my code above gives me a .gdx file with only 1 entry - the last (3rd) randomly selected element of the set "codes". Some help on this will be deeply appreciated.
You could use an addition "scenario index" to store the results in a parameter while executing the loop and export everything at once at the end like this:
SET
codes /aaa, aab, aac, aad, aae, aaf, aag, aah, aaj, aak, aal/
scenario /1*3/;
scalar
randnumber;
parameter
selected(scenario,codes);
loop(scenario,
randnumber = uniformint(1,11);
selected(scenario,codes)=ord(codes)=randnumber;
);
execute_unload 'output.gdx',selected;
display selected;
I help that helps!
Lutz
I'm using boost log and I want to make basic log principal file: new error log at the beginning of each hour (if error exists), and to name it like "file_%Y%m%d%H.log".
I have 2 problems with this boost library:
1. How to rotate file at the beginning of each hour?
This isn't possible with rotation_at_time_interval parameter because it creates new file regarding first written record in file, and the hour in file name doesn't match that rule. Is it possible to have multiple rotation_at_time_point for one file in sink or is there some other solution?
2. When file exceed some size I want it to start new file and in that case it should append some index to file name. With adding rotation_size parametar and %N to file name it will increment N all the time while application is running. I want that N to be reset at the beginning of each hour, just as my file name changes. Does anybody have any idea how to do that with this boost log library?
This is basic principal in creating log files in industry. I really don't understand how this can't be done with library which is dedicated for creating log files.
Library itself doesn't provide a way to rotate file at the begging of every hour, but i had same problem so i used a function wrapper, which return true on begging of every hour.
I find this way better for me, because i can controll efficency of code.
from boost.org:
bool is_it_time_to_rotate();
void init_logging(){
boost::shared_ptr< sinks::text_file_backend > backend =
boost::make_shared< sinks::text_file_backend >(
keywords::file_name = "file_%5N.log",
keywords::time_based_rotation = &is_it_time_to_rotate
);
}
For a second question i really dont undrestand it well.
I have a short app that check if my music files are names to a specific routine (track number and then track name), but I'm getting an error whenever there are no files that need renaming, because the array in initialised, but the first item is nothing, null, empty (however VB refers to it).
To try and fix this, I'm running this check, but I'm still getting an error.
' Array declared like this
Dim nc_full_names(0) As String
<Code goes here to ReDim 'nc_full_names' and add the file name to the array, if a file needs renaming>
For i = 0 To UBound(nc_full_names)
'Checking if the array element actually has something in it like this
If Not nc_full_names Is Nothing Then
My.Computer.FileSystem.RenameFile(nc_full_names(i), nc_new_names(i))
Else
Exit For
End If
Next i
Here is the error that I am getting -
Argument cannont be nothing. Parameter name: file
Can anyone tell me the correct way to carry out this check?
I found that the answer was to check the first element in the array, as opposed the array itself. Thus, changing this...
If Not nc_full_names Is Nothing Then
...to this...
If Not nc_full_names(i) Is Nothing Then
...works just fine.
You can also start with a truly empty array:
Dim nc_full_names(-1) As String
Now nc_full_names.Length = 0.