Copy character values from character array variable to character (string) variable - progress-4gl

this is my issue
define varibale MyArray as character extent 40 no-undo.
define variable Mychara as character no-undo.
Mychara = "hai this is checking how to copy values"
Now i want to copy this string to my "MyArray". So that it should be as follows
MyArray[1]=h ,MyArray[2]=a ,MyArray[3]=i ,MyArray[4]="" ,MyArray[5]=t ,MyArray[6]=h
and so on...
So how to do it?

Given your code-example, this should do the trick:
define variable MyArr as character EXTENT 40 no-undo.
define variable Mychara as character no-undo.
Mychara = "hai this is checking how to copy values".
DEF VAR i AS INT NO-UNDO.
DO i = 1 TO 40:
MyArr[i] = SUBSTRING(MyChara,i,1).
END.
A caveat though: this means that you have to know the (maximum) size of your String beforehand, to define the array size appropriately.

little bit dynamically ;)
define variable MyArr as character EXTENT no-undo.
define variable Mychara as character no-undo.
DEF VAR i AS INT NO-UNDO.
Mychara = "hai this is checking how to copy values".
EXTENT (MyArr) = LENGTH (Mychara).
DO i = 1 TO EXTENT (MyArr):
MyArr[i] = SUBSTRING(MyChara,i,1).
END.

define var l_mychara as integer no-undo.
define variable MyArray as character format "x(5)" extent 40 no-undo.
define variable Mychara as character format "x(5)" no-undo.
def var i as int init 1.
Mychara = "hai this is checking how to copy values".
assign l_mychara = length(Mychara).
do while i <= l_mychara.
assign myarray[i] = substring(mychara,i,1).
if myarray[i] = "" then assign myarray[i] = "blank".
i = i + 1.
end.
disp Myarray .

Related

How to get common words from two different sentences by using ENTRY function in progress4gl?

How to get common words from two different sentences by using ENTRY function in progress4gl?
define variable a1 as character no-undo initial "hi dude do".
define variable a2 as character no-undo initial "hi man it".
define variable cnta as character.
define variable cntb as character.
define variable cntc as character.
define variable i as integer.
define variable j as integer.
do i = 1 to 3:
entry (i,a1,"").
do j = 1 to 3:
entry (j,a2,"").
end.
end.
/* assign cntc = cnta matches cntb . */
define variable a1 as character no-undo initial "hi dude do".
define variable a2 as character no-undo initial "hi man it".
define variable common as character no-undo.
define variable cc as integer no-undo.
define variable ii as integer no-undo.
define variable jj as integer no-undo.
define variable n1 as integer no-undo.
define variable n2 as integer no-undo.
n1 = num-entries( a1 ).
n2 = num-entries( a2 ).
do ii = 1 to n1:
do jj = 1 to n2:
if entry ( ii, a1, " ") = entry( jj, a2, " " ) then
do:
cc = cc + 1.
common = common + " " + entry( ii, a1, " " ).
end.
end.
end.
display trim( cc ) common.
Notes:
The TRIM() function is just to clean up the "common" string so it doesn't have an extra space.
For performance reasons it is good to get in the habit of obtaining NUM-ENTRIES() outside the loop rather than with every iteration of the loop. It doesn't make much difference for small strings but for large strings it can have quite an impact.
1./*if i need to get the n number of words in two sentences from the user at the run time , how to compare and the get the common words.
the following code compares and displays only first letter of the two sentence.
*/
define variable a1 as character no-undo.
define variable a2 as character no-undo.
define variable common as character no-undo.
define variable a1 as character FORMAT "x(64)" no-undo /* initial "hi d do" */.
define variable a2 as character FORMAT "x(64)" no-undo /* initial "hi d it" */.
define variable common as character FORMAT "x(64)" no-undo.
define variable c1 as character FORMAT "x(64)" no-undo.
define variable x as character FORMAT "x(64)" no-undo.
define variable y as character FORMAT "x(64)" no-undo.
define variable cc as integer no-undo initial 0.
define variable ii as integer no-undo.
define variable jj as integer no-undo.
define variable n1 as integer no-undo.
define variable n2 as integer no-undo.
set a1.
n1 = num-entries( a1,"" ).
set a2.
n2 = num-entries( a2,"" ).
do ii = 1 to n1:
do jj = 1 to n2:
if entry ( ii,a1, " ") matches entry( jj,a2, " " ) then
do:
common = entry( ii, a1, " " ).
display common .
end.
end.
end.

is it possible to use MaximumFuntion within an Entry Funciton in Progress 4gl

I am new to progress and I am trying to figure out how to get this working. My task is to Get a list of integer values from user as semi colon separated and message the highest and lowest value on that list. Till now I have used an entry function to help me get just the integers entered by the user one after another. like so
repeat I = 1 to totalEntries:
m = entry (I, Userinput, ";").
display m.
end.
After this I would like to find out the maximum value of all the entries. how can I do this since maximum function accepts more than one value for comparison.
There is no built in function to give a maximum or minimum number from given list of numbers. You need to write your own logic as in most of the programming languages. Here is an example:
DEF VAR i AS INT.
DEF VAR nlist AS CHAR INIT "1;2;7;3;6;9".
DEF VAR imin AS INT.
DEF VAR imax AS INT.
imin = INTEGER(ENTRY (1, nlist, ";")).
imax = INTEGER(ENTRY (1, nlist, ";")).
REPEAT i = 2 TO NUM-ENTRIES(nlist, ";"):
IF INTEGER(ENTRY(i, nlist, ";")) > imax THEN
imax = INTEGER(ENTRY(i, nlist, ";")).
IF INTEGER(ENTRY(i, nlist, ";")) < imin THEN
imin = INTEGER(ENTRY(i, nlist, ";")).
END.
MESSAGE imax.
MESSAGE imin.
As Austin sad, there is no built-in function in Progress to give a maximum or minimum number from a list.
In your comment, you've mentioned that MAXIMUM(1,2,3) worked. Yes, it works, but you have to figure that you're passing three parameters to the function, not a list of numbers inside a single CHAR variable.
To solve your problem you can use the solution given by Austin or you can use two functions that receive a CHAR variable with semi colon separated values and return maximum or minimum values.
Here is an example, based on your code.
FUNCTION iMax RETURNS INTEGER
( INPUT pData AS CHAR ):
DEF VAR iOutput AS INT NO-UNDO.
DEF VAR iCount AS INT NO-UNDO.
iOutput = ?.
DO iCount = 1 TO NUM-ENTRIES(pData,';'):
IF iOutput = ? THEN DO:
iOutput = INT(ENTRY(iCount,pData,';')).
NEXT.
END.
iOutput = MAX(iOutput,INT(ENTRY(iCount,pData,';'))).
END.
RETURN iOutput.
END FUNCTION.
FUNCTION iMin RETURNS INTEGER
( INPUT pData AS CHAR ):
DEF VAR iOutput AS INT NO-UNDO.
DEF VAR iCount AS INT NO-UNDO.
iOutput = ?.
DO iCount = 1 TO NUM-ENTRIES(pData,';'):
IF iOutput = ? THEN DO:
iOutput = INT(ENTRY(iCount,pData,';')).
NEXT.
END.
iOutput = MIN(iOutput,INT(ENTRY(iCount,pData,';'))).
END.
RETURN iOutput.
END FUNCTION.
/****************/
Define variable NumberEntry as character view-as fill-in no-undo.
Define variable UsersInput as character no-undo.
Define variable i as integer no-undo.
Define variable totalEntries as integer no-undo.
Define variable m as character no-undo.
Define variable n as character no-undo.
Define button bFind.
Define frame main numberEntry label "Enter numbers separated by semi colon" skip
bFind label "Find Max and Min" with side-labels. /*Trigger for button*/
On choose of bFind in frame main do: /*Retrieve the users input*/
Usersinput = (numberEntry:screen-value). /*to find out how many characters the user has enterd.*/ totalEntries = num-entries(UsersInput,';'). Display totalentries. /*Logic to extract Users input values one by one.*/
Repeat i = 1 to totalEntries: M = entry(i, UsersInput, ";").
Display m.
End. /*Logic to find the maximum element. */ .....
MESSAGE 'MAXIMUM :' iMax(UsersInput) SKIP
'MINIMUM :' iMin(UsersInput)
VIEW-AS ALERT-BOX INFO BUTTONS OK.
END.
VIEW FRAME main.
ENABLE ALL WITH FRAME main.
WAIT-FOR CHOOSE OF bfind.
You can call iMax() or iMin() and get MAX or MIN values from Progress MAXIMUM and MINIMUM function using a CHAR list of INTEGER values separated by semi colons without need to make a full code block to do the comparision and get the information for each situation that presents necessary.
Hope it helps.

Length of Array in progress?

Given two arrays, ( for example 1,2,3,4,5 and 2,3,1,0). Find which number of first array is not present in the second array. How can i get Length of Arrays in progress 4gl ?
If the object in question is an ARRAY, rather than a LIST, you use the EXTENT() function to determine the number of elements. Using arrays:
define variable a1 as integer no-undo extent 5 initial [ 1, 2, 3, 4, 5 ].
define variable a2 as integer no-undo extent 4 initial [ 2, 3, 1, 0 ].
define variable i as integer no-undo.
define variable j as integer no-undo.
define variable ok as logical no-undo.
do i = 1 to extent( a1 ):
ok = no.
do j = 1 to extent( a2 ):
if a1[i] = a2[j] then ok = yes.
end.
if ok = no then message a1[i] "is not in a2".
end.
To have the length of a list (number of items of the list), you can use NUM-ENTRIES() function.
To know if an item is present in a list, you can use LOOKUP() function.
So for your example, you can do something like this:
DEFINE VARIABLE wclist1 AS CHARACTER NO-UNDO INITIAL "1,2,3,4,5".
DEFINE VARIABLE wclist2 AS CHARACTER NO-UNDO INITIAL "2,3,1,0".
DEFINE VARIABLE wc-list-no-present AS CHARACTER NO-UNDO.
DEFINE VARIABLE wi-cpt AS INTEGER NO-UNDO.
/* For each items of list1 */
DO wi-cpt = 1 TO NUM-ENTRIES(wclist1, ","):
/* Test if the item is in list 2 */
IF LOOKUP(ENTRY(wi-cpt, wclist1, ","), wclist2, ",") = 0
THEN
wc-list-no-present = wc-list-no-present + "," + ENTRY(wi-cpt, wclist1, ",").
END.
/* TRIM is to remove the first "," */
DISPLAY TRIM(wc-list-no-present, ",").
def var a as int extent 5 initial [1,2,3,4,5] no-undo.
def var b as int extent 4 initial [2,3,1,0] no-undo.
def var i as int no-undo.
def var j as int no-undo.
loop:
repeat i = 1 to extent(a):
repeat j = 1 to extent(b):
if a[i] = b[j]
then next loop.
end.
Display a[i] "not in b array" format "x(20)".
end.

OpenEdge: how to remove HTML tags from a string?

I have tried doing this:
REPLACE(string, "<*>", "").
but it doesn't seem to work.
REPLACE doesn't work like that. There's no wildcard matching in it.
I've included a simple way of doing this below. However, there's lots of cases that this wont work in - non well formed html etc. But perhaps you can start here and move forward by yourself.
What I do is look for < and > in the text and replace everything between it with a pipe (|) (you could select any character - preferably something not present in the text. When that's done all pipes are removed.
Again, this is a quick and dirty solution and not safe for production...
PROCEDURE cleanHtml:
DEFINE INPUT PARAMETER pcString AS CHARACTER NO-UNDO.
DEFINE OUTPUT PARAMETER pcCleaned AS CHARACTER NO-UNDO.
DEFINE VARIABLE iHtmlTagBegins AS INTEGER NO-UNDO.
DEFINE VARIABLE iHtmlTagEnds AS INTEGER NO-UNDO.
DEFINE VARIABLE lHtmlTagActive AS LOGICAL NO-UNDO.
DEFINE VARIABLE i AS INTEGER NO-UNDO.
DO i = 1 TO LENGTH(pcString):
IF lHtmlTagActive = FALSE AND SUBSTRING(pcString, i, 1) = "<" THEN DO:
iHtmlTagBegins = i.
lHtmlTagActive = TRUE.
END.
IF lHtmlTagActive AND SUBSTRING(pcString, i, 1) = ">" THEN DO:
iHtmlTagEnds = i.
lHtmlTagActive = FALSE.
SUBSTRING(pcString, iHtmlTagBegins, iHtmlTagEnds - iHtmlTagBegins + 1) = FILL("|", iHtmlTagEnds - iHtmlTagBegins).
END.
END.
pcCleaned = REPLACE(pcString, "|", "").
END PROCEDURE.
DEFINE VARIABLE c AS CHARACTER NO-UNDO.
RUN cleanHtml("This is a <b>text</b> with a <i>little</i> bit of <strong>html</strong> in it!", OUTPUT c).
MESSAGE c VIEW-AS ALERT-BOX.

How to test if string is numeric using Progress 4GL

Does Progress 4GL have a function for testing whether a string is numeric, like PHP's is_numeric($foo) function?
I've seen the function example at http://knowledgebase.progress.com/articles/Article/P148549 to test if a character in a string is numeric. Looks like it has a typo, btw.
But I would think the language would be a built-in function for this.
I was looking at this myself recently. The approved answer given to this doesn't work in 100% situations.
If the user enters any of the following special string characters: ? * - or + the answer won't work.
A single plus or minus(dash) is converted to 0 which you may not want.
A single question mark character is valid value which progress recognises as unknown value at which again you may not want.
A single or group asterisks on their own also get converted to 0.
If you run the following code you'll see what I mean.
DISP DECIMAL("*")
DECIMAL("**")
DECIMAL("?")
DECIMAL("+")
DECIMAL("-").
The following additional code maybe useful to get around this
DEFINE VARIABLE iZeroCode AS INTEGER NO-UNDO.
DEFINE VARIABLE iNineCode AS INTEGER NO-UNDO.
DEFINE VARIABLE chChar AS CHARACTER NO-UNDO.
ASSIGN iZeroCode = ASC("0")
iNineCode = ASC("9")
chChar = SUBSTRING(cNumber,1,1).
IF NOT(ASC(chChar) >= iZeroCode AND ASC(chChar) <= iNineCode) THEN DO:
MESSAGE "Invalid Number..." VIEW-AS ALERT-BOX.
END.
Do not need a function can jsut do a straight conversion.
ASSIGN dNumber = DECIMAL(cNumber) NO-ERROR.
IF ERROR-STATUS:ERROR THEN
DO:
{Handle issues}
END.
or if it is always whole numbers can use INTEGER instead of DECIMAL.
The language does not have a built-in "isNum()" type of function.
An alternative to the kbase method would be:
function isNum returns logical ( input s as character ):
define variable n as decimal no-undo.
assign
n = decimal( s )
no-error
.
return ( error-status:num-messages = 0 ).
end.
display isNum( "123" ) isNum( "xyz" ).
This code handles any numeric strings - even if the used Character is longer than the max Decimal length etc.
FUNCTION isNumeric RETURNS LOGICAL (textvalue AS CHAR):
DEF VAR i AS INT NO-UNDO.
IF textvalue = ? THEN RETURN TRUE.
DO i = 1 TO (LENGTH(textvalue) - 1):
INT(SUBSTRING(textvalue, i, (i + 1))) NO-ERROR.
IF ERROR-STATUS:ERROR THEN RETURN FALSE.
END.
RETURN TRUE.
END FUNCTION.
Works 100% of the time
FUNCTION is-num RETURNS LOGICAL
(INPUT cString AS CHARACTER):
DEFINE VARIABLE iZeroCode AS INTEGER NO-UNDO.
DEFINE VARIABLE iNineCode AS INTEGER NO-UNDO.
DEFINE VARIABLE cChar AS CHARACTER NO-UNDO.
DEFINE VARIABLE iCount AS INTEGER NO-UNDO.
DO iCount = 1 TO LENGTH(cString):
ASSIGN iZeroCode = ASC("0")
iNineCode = ASC("9")
cChar = SUBSTRING(cString,iCount,1).
IF NOT(ASC(cChar) >= iZeroCode AND ASC(cChar) <= iNineCode) THEN DO:
RETURN FALSE.
END.
END.
RETURN TRUE.
END.