Encapsulate SCADA Basic logic to a library

18 Posts
3 Users
0 Likes
93 Views
(@j.becker@pcvue.de)
Posts: 0
New Member Guest
 

Hello all again,

i would like to extend some SCADA Basic functionality, like String-manipulation, e.g. Replace, which is not part of SCADA in PcVue 10, and encapsulate the logic in one library, lets call it "Extended SCADA Basic".

As you always / very often need return values (e.g. you want to get the manipulated String), you cannot use the "Program("Execute / Function",...)" function, because there is no return value.

Now you can use a global variable to store the return value. Or if you create functions inside the global program, you also can access directly the function and retrieve the return value.

My question is now:
Is it possible to encapsulate the logic to a library and use the functions as they were in the global program?

 
Posted : 31/03/2015 6:34 pm
n.kunzer
(@n-kunzerarcinfo-com)
Posts: 1236
Member Moderator
 

HI Johannes,

Firstly you must know that 1 library exist already for that kind of useful programs. Name is UTILITIES.

About your question: No. There is only 1 possible global program loaded. As you said the only way returning a result is by using a global variable. You could also use a PcVue variable but you would have to manage the asynchronous behaviour.

You can also explain in the comment of your functions that it must be copied in the Global program.

By the way, could you explain what String-manipulation your functions are doing?

Nico

 
Posted : 01/04/2015 9:19 am
(@j.becker@pcvue.de)
Posts: 0
New Member Guest
 

Hello,

here the function that I needed often and that brought me to the idea: Ability to replace a character in a string. I had often similar issues, like separate by character. But I started with this:

'String manipulation
'<<>>
sub s_replace_c(s,old_c,new_c)
'
'info: Be aware to use " " for special chars like " ' " or " n "
's = string to manipulate
'old_c = char to replace
'new_c = char to set instead
'i = counter
't = temporary manipulated string

dim i as integer;
dim t as str;
for(i=1;i<=len(s);i++)
if(CmpString(Right(left(s, i),1),old_c)==0) then
t = AddString(Left(s,i-1),new_c);
s = AddString(t,Right(s,len(s)-i));
end if
next
return s;
end sub

 
Posted : 01/04/2015 4:46 pm
n.kunzer
(@n-kunzerarcinfo-com)
Posts: 1236
Member Moderator
 

Hi Johannes,

Completing your job i provide here a function that is replacing strings instead only 1 char. Of course it's working for 1 char too 😉

Sub s_replace_string(s,old_s,new_s)

Dim iSize as integer;
Dim sTmp as str;
Dim i as integer;

iSize = LEN(old_s);

for(i=0;i<=LEN(s)-1;i++)
if(CMPSTRING( MID(s, i , iSize), old_s)==0) then
sTmp = ADDSTRING(sTmp, new_s);
i = i + isize - 1;
else
sTmp = ADDSTRING(sTmp, MID(s, i, 1 ) );
end if

next
return(sTmp);

End Sub

 
Posted : 02/04/2015 7:09 am
(@j.becker@pcvue.de)
Posts: 0
New Member Guest
 

Hello Nico,

thank you very much.

 
Posted : 02/04/2015 11:40 am
(@j.becker@pcvue.de)
Posts: 0
New Member Guest
 

hi, another helper_function for SCADA Basic:
maybe helpfull for somebody, or somebody wants to improve.

StartsWith(s,s_part)
Returns 1 if s_part starts with s and 0, if not.

sub helper_startsWith(s,s_part)
dim count as integer;
dim i as integer;
dim match as integer;
dim tmp_s as str;
dim tmp_c as str;
dim tmp_c_part as str;

match = 1;
count = len(s_part);

for(i=0;i<count;i++)

tmp_s = Left(s,count);
tmp_c = Left(Right(tmp_s,count-i),1);
tmp_c_part = Left(Right(s_part,count-i),1);

if(CmpString(tmp_c,tmp_c_part)!=0) then
match = 0;
break;
end if

next

return(match);
end sub

 
Posted : 01/12/2017 6:12 am
(@j.becker@pcvue.de)
Posts: 0
New Member Guest
 

Hi,
another one:
GET Parent-Branch from Branch:

sub helper_getParentBranch(s_branch)
dim p_branch as str;
dim count as integer;
dim pos as integer;
dim i as integer;
dim tmp as str;

p_branch = "-1";
count = len(s_branch);

for(i=0;i<count;i++)

tmp = Left(Right(s_branch,1+i),1);
if(CmpString(tmp,".")==0) then
pos = i;
p_branch = left(s_branch,count - pos-1);
break;
end if

next

return P_branch;

end sub

 
Posted : 01/12/2017 7:15 pm
n.kunzer
(@n-kunzerarcinfo-com)
Posts: 1236
Member Moderator
 

Hi Johannes,

About this one:
GET Parent-Branch from Branch:

Personally, looping a string is not so elegant and difficult to understand.
I prefer this way:

Sub GetFirstBranch(sBranch)

	Dim hbuf as long;
	Dim sBranch1 as str;
	
	hbuf = alloc_buffer(250);
	Put_Buffer(hbuf, 0, sBranch);
	
	sBranch1 = Asciifield("STR", hbuf, 1, ".");
	free_buffer(hbuf);

	return(sBranch1);
	
End Sub

Also it is better because you can adapt this code to return any branch like that:

Sub GetSubBranch(sBranch, Index)

	Dim hbuf as long;
	Dim sSubBranch as str;
	
	hbuf = alloc_buffer(250);
	Put_Buffer(hbuf, 0, sBranch);
	
	sSubBranch = Asciifield("STR", hbuf, Index, ".");
	free_buffer(hbuf);

	return(sSubBranch);
	
End Sub
 
Posted : 04/12/2017 9:56 am
n.kunzer
(@n-kunzerarcinfo-com)
Posts: 1236
Member Moderator
 

About this
StartsWith(s,s_part)
Returns 1 if s_part starts with s and 0, if not.

I am not sure to really understand your code (looping in a string again....).
So, I did something looking more simple.

Sub StartsWith(s,s_part)

	Dim sTmp as str;
	
	sTmp = Left(s_part, len(s));
	
	if (Cmpstring(sTmp, s) == 0) then
		Return (1);
	else
		Return(0);
	end if

End Sub
 
Posted : 04/12/2017 10:02 am
(@j.becker@pcvue.de)
Posts: 0
New Member Guest
 

hi,
about starts with:
yes you are right, later in the day I changed also my code like this, but did not post it here.
Thanks.

 
Posted : 04/12/2017 1:27 pm
(@j.becker@pcvue.de)
Posts: 0
New Member Guest
 

Hi,
about getBranch():
this is pretty cool. I did not think about that. Thank you.

 
Posted : 04/12/2017 1:29 pm
f.martin
(@f-martinarcinfo-com)
Posts: 148
Member Admin
 

About StartsWith, 2 additional things:
- test is s_part is longer than s, otherwise it will return 1 when s_part start with s...
- a NoCase function (unfortunately it is not possible to have optional parameters in user functions)

Sub StartsWith(s, s_part)

	Dim sTmp as str;
	
	if (len(s_part) > len(s)) then
		Return (0);
	end if
	
	sTmp = Left(s_part, len(s));
	
	if (Cmpstring(sTmp, s) == 0) then
		Return (1);
	else
		Return (0);
	end if

End Sub

Sub StartsWithNoCase(s, s_part)

	Dim sTmp as str;
	
	if (len(s_part) > len(s)) then
		Return (0);
	end if
	
	s_part = ucase(s_part);
	s = ucase(s);
	
	sTmp = Left(s_part, len(s));
	
	if (Cmpstring(sTmp, s) == 0) then
		Return (1);
	else
		Return (0);
	end if

End Sub
 
Posted : 05/12/2017 4:55 pm
(@j.becker@pcvue.de)
Posts: 0
New Member Guest
 

Maybe it should be a new function in SCADA Basic?

 
Posted : 05/12/2017 4:59 pm
n.kunzer
(@n-kunzerarcinfo-com)
Posts: 1236
Member Moderator
 

Yep, good point Florent...

 
Posted : 05/12/2017 5:13 pm
f.martin
(@f-martinarcinfo-com)
Posts: 148
Member Admin
 

Maybe it should be a new function in SCADA Basic?

=> Whishlist 😉 (with EndsWith, Contains, case sensitive Compare, Split, ...)

 
Posted : 05/12/2017 6:14 pm