Hi everybody,
I m a bullshit in vba and I have this question from my customer :
"I interface controls made in .NET and I manage events through VBA.
I'm writing instructions from this code but it's not logging in as if I were doing it from an animation or in scada basic."
Example of the code :
Variables(Me.Branch + ".Mode").Value = 1
The variable is well written but no trace in the log. If not, is it possible to manually add traces to the log via a vba function?
Does anyone can help me?
thanks
Manu
It's working fine here...
Florent, I tried and it didn't work: No 'Command' event in the Log viewer. What did I miss?
nico
Which logs are we talking about ?
- Change to 0/1 ?
- Command to 0/1 ?
I record the "Changes" with animation, SCADA and VBA.
Commands are only recorded with animation. As SCADA Basic and VBA can be triggered without user action, it seems quite normal.
Manu, can you give us more details on what is expected.
The goal is to log the command 0/1.
that's why he asks : If not, is it possible to manually add traces to the log via a vba function?
No, there is no function to directly insert events to the log lists. It would be a perfect method to falsify records...
And I unadvise directly recording it in the archive unit.
As I wrote, a direct write with SCADA Basic has the same result (by default), the Command event is not logged. To make it work you have to use SYSTEM("OPERATORMODE",1)
A small trick would be to use a text variable to trigger a SCADA Basic event, with GETARG("VARVALUE_TEXT") to retrieve the variable and value to write.
Please, talk about log event and log list. Traces is something elses, except if you're talking about the event viewer
Unfortunately, the OPertorMode trick is only available for Scada Basic and doesn't apply to VBA 🙁
So, the text variable trick given by Florent is, personally, not the way I do that kind of job.
I prefer the following:
- Create the TEXT variable GENERAL.VBA_SET
- Configure the archve unit to store the Text Attribute 3
- For each bit variable the VBA is supposed to set
a. Configure one Text Attribute 3 with the string GENERAL.VBA_SET
b. Before setting the bit, set the GENERAL.VBA_SET value with the message you want to display in the log viewer
c. Set the bit
Then display the Differed attribute 3 in the Log Viewer.
Nico
Just in case we speak about event viewer there is a new feature since version 12.0.16 :
New method to log messages (SPR #67826)
A new method LogInformation is available in VBA on the Project object. It can be used to send
log messages to the Event Viewer.
ThisProject.LogInformation LogLevel,LogMsg
Where LogLevel can take value 1, 2 or 3, and LogMsg is the message to be logged (string)
• 1 = Information
• 2 = Warning
• 3 = Error
@Ludo: note that these messages are not forwarded to Syslog
@Nicolas: it still not records the "Command to 1/0" event, and you can update the tatt in VBA too.
Here my SCADA Basic function
Dim handle as long;
Dim textValue as str;
Dim varName as str;
Dim varValue as str;
Dim varType as integer;
'Get the value that triggered the event
'In case of consecutive writes, the realtime value may have already changed !
textValue = GETARG("VARVALUE_TEXT");
if (CmpString(textValue, "") == 0) then
return;
end if
'put the string into a buffer to get the different parts
handle = Alloc_Buffer(Len(textValue) + 1);
Put_Buffer(handle, 0, textValue);
'Read the "parameters"
'here a simple format #
' could be something different like ### or ##
varName = ASCIIFIELD("STR", handle, 1, "#");
varValue = ASCIIFIELD("STR", handle, 2, "#");
'don't forget to free the buffer
FREE_BUFFER(handle);
'Execute the requested action (here write a variable)
SYSTEM("OPERATORMODE", 1);
varType = VARIABLE("GET_TYPE", varName);
if (varType == 2) then 'Register
?varName = DVAL(varValue);
else if (varType == 4) then 'Text
?varName = varValue;
else 'Bit(1) or Alarm(8)
?varName = IVAL(varValue);
end if
end if
'Init the trigger variable (optional)
SYSTEM("OPERATORMODE", 0);
varName = GETARG("VARNAME");
?varName = "";
and the call from the VBA
[General.VBA_Set] = "Bit01#0"
[General.VBA_Set] = "Register02#10"
[General.VBA_Set] = "Register01#20"


