How do you let user input a lengthy string into a variable?
I know this is trivial but I haven't been able to achieve it yet.
Here is what I've tried :
DEF VAR filter AS CHAR NO-UNDO.
UPDATE filter.
The value was always truncated to only a few characters. So, I've tried adding a format like so.
UPDATE filter FORMAT "X(318)":U.
Which give error
FILL-IN filter will not fit in FRAME
This program is only used by power user, so it doesn't have a frame to make thing pretty.
The basic console is all that is needed.
318 characters would have been better than nothing, but it would still not be ideal because user may copy-paste a longer string. Note that user wouldn't not paste any string that exceed 32000 characters.
Here is what the user input would looks like.
value1,value2,value3,value4,value5,value6,value7,value8,value9,value10,value11
I occasionally use something along these lines:
/* editlong.p
*
*/
define variable longText as character no-undo format "x(1000)"
view-as fill-in size 40 by 1
label "Long Text"
.
update longText "...".
The format "x(1000)" could just as easily be format "x(32000)". But whatever it is, it will be the hard limit on what someone can enter.
You could also do multi-line entry like this:
define variable longText as character no-undo format "x(1000)"
view-as editor inner-chars 30 inner-lines 5
large no-word-wrap
label "Long Text"
.
update longText "...".
Related
I am trying to import a .csv file to match the records in the database. However, the database records has leading zeros. This is a character field The amount of data is a bit higher side.
Here the length of the field in database is x(15).
The problem I am facing is that the .csv file contains data like example AB123456789 wherein the database field has "00000AB123456789" .
I am importing the .csv to a character variable.
Could someone please let me know what should I do to get the prefix zeros using progress query?
Thank you.
You need to FILL() the input string with "0" in order to pad it to a specific length. You can do that with code similar to this:
define variable inputText as character no-undo format "x(15)".
define variable n as integer no-undo.
input from "input.csv".
repeat:
import inputText.
n = 15 - length( inputText ).
if n > 0 then
inputText = fill( "0", n ) + inputText.
display inputText.
end.
input close.
Substitute your actual field name for inputText and use whatever mechanism you are actually using for importing the CSV data.
FYI - the "length of the field in the database" is NOT "x(15)". That is a display formatting string. The data dictionary has a default format string that was created when the schema was defined but it has absolutely no impact on what is actually stored in the database. ALL Progress data is stored as variable length length. It is not padded to fit the display format and, in fact, it can be "overstuffed" and it is very, very common for applications to do so. This is a source of great frustration to SQL reporting tools that think the display format is some sort of length limit. It is not.
I use below code and its working fine. I don't want to change temp table field(dActiveDate) type but please help me to change the date format.
Note - Date format can be changed by user. It can be YY/MM/DD or DD/MM/YYYY or MM/DD/YY and so on...
DEFINE TEMP-TABLE tt_data NO-UNDO
FIELD cName AS CHARACTER
FIELD dActiveDate AS DATE.
CREATE tt_data.
ASSIGN
tt_data.cName = "David"
dActiveDate = TODAY
.
OUTPUT TO value("C:\Users\ast\Documents\QRF\data.csv").
PUT UNFORMATTED "Name,Activedate" SKIP.
FOR EACH tt_data NO-LOCK:
EXPORT DELIMITER "," tt_data. /* There are more than 15 fields available so using export delimeter helps to have less lines of code*/
END.
OUTPUT CLOSE.
As this a "part two" of this question: How to change date format based on variable initial value? why not build on the answer there?
Wrap the dateformat part in a function/procedure/method and call it in the EXPORT statement. The only change required will be to specify each field rather than just the temp-table.
EXPORT DELIMITER ","
dateformat(tt_data.dactivedate, cDateFormat)
tt_data.cName
This assumes that there's a function called dateformat that takes the date and format and returns a string with the formatted date (as in the previous question).
"and so on..." needs to be specified. Depending on the specification you may have to resort to a custom function like Jensd's answer.
If you can constrain the formats allowed, you can use normal handling by using:
session:date-format = "ymd" / "mdy" / "dmy".
session:year-offset = 1 / 1950. // for four vs two digit year
How you populate these two variables can be done in similar fashion as in the other question.
You may need to reset these session attributes to their initial state in a finally block.
I'm using a window(.w) that has a button that passes a variable to a procedure(.p), does its magic and then needs to return the results in a temp-table back to the window for display.
The .w file
Definitions
DEFINE TEMP-TABLE Return_Results
FIELD tt_var1Return AS CHARACTER FORMAT "x(20)"
FIELD tt_var2Return AS CHARACTER FORMAT "x(30)"
FIELD tt_var3Return AS CHARACTER FORMAT "x(30)"
FIELD tt_var4Return AS CHARACTER FORMAT "x(30)"
.
Button code
ON CHOOSE OF RecordFinder IN FRAME Dialog-Frame
DO:
DEFINE VARIABLE varInput AS CHARACTER NO-UNDO
DEFINE VARIABLE Return_Results REFERENCE-ONLY. /* <--- I'm pretty sure this is the problem */
varInput = Fill-In:SCREEN-VALUE.
RUN RecordFinder.p(INPUT varInput, OUTPUT Return_Results).
FOR EACH Return_Results:
Display Return_Results.
END.
END.
The .p file
i'm omitting some stuff that i think may not be necessary, but it basically takes the input variable, matches it and generates a temp-table from the results and assign those records to a new temp-table that will get passed back.
Definitions
DEFINE INPUT PARAMETER windowInput AS CHARACTER NO-UNDO.
DEFINE OUTPUT PARAMETER Results_Output
DEFINE TEMP-TABLE Original_tt
FIELD tt_var1Original AS CHARACTER FORMAT "x(20)"
FIELD tt_var2Origianl AS CHARACTER FORMAT "x(30)"
FIELD tt_var3Original AS CHARACTER FORMAT "x(30)"
FIELD tt_var4Original AS CHARACTER FORMAT "x(30)"
.
DEFINE TEMP-TABLE Return_tt
FIELD tt_var1Return AS CHARACTER FORMAT "x(20)"
FIELD tt_var2Return AS CHARACTER FORMAT "x(30)"
FIELD tt_var3Return AS CHARACTER FORMAT "x(30)"
FIELD tt_var4Return AS CHARACTER FORMAT "x(30)"
.
*additional code that works*
The next bit of code is for sorting the result of the temp table where it matches the input variable
FOR EACH Original_tt WHERE Original_tt.Var1 = windowInput:
CREATE Return_tt.
BUFFER-COPY Original_tt TO Results_tt
Return_tt.tt_var1Return = Original_tt.tt_var1Original.
Return_tt.tt_var2Return = Original_tt.tt_var2Original.
Return_tt.tt_var3Return = Original_tt.tt_var3Original.
Return_tt.tt_var4Return = Original_tt.tt_var4Original.
/* This is where I know I'm wrong */
/* I figured you could assign the Return_tt to the output variable */
Results_Output = Return_tt.
END.
I hope this not too convoluted.
The doc at https://docs.progress.com/bundle/abl-reference/page/Parameter-passing-syntax.html has detail on the parameter passing syntax (though no decent example).
In the called program (.p) you need to define the parameters
DEFINE INPUT PARAMETER windowInput AS CHARACTER NO-UNDO.
DEFINE OUTPUT PARAMETER TABLE FOR Return_tt.
In the caller (.w), you say the following
RUN RecordFinder.p(INPUT varInput, OUTPUT TABLE Return_Results).
Now you have the data in your caller.
It's a deep copy (so the .W gets its very own copy in memory). This may cause you performance problems (since a copy must be made), although there are reasons for making deep copies too.
You can turn the deep (by value) call into a shallow (by reference) call quite easily.
RUN RecordFinder.p(INPUT varInput, OUTPUT TABLE Return_Results BY-REFERENCE).
Some further doc at https://docs.progress.com/bundle/develop-abl/page/Passing-a-temp-table-by-reference.html . You don't need to define the temp-table as REFERENCE-ONLY in the caller.
DEFINE VARIABLE cDateTime AS CHARACTER NO-UNDO.
DEFINE TEMP-TABLE tt_data NO-UNDO
FIELD DateTime AS DECIMAL FORMAT "->>,>>9.99".
ASSIGN
cDateTime = "20191604121566".
CREATE tt_data.
ASSIGN
tt_data.DateTime = DECIMAL(cDateTime) /* Message Date and Time */
But it says:
"Value cannot be displayed using ->>>,>>>,>>9.999999".
Could you please help this case and tell me what is wrong here?
The code that you show does not result in the error that you are reporting.
I'm guessing that you have a DISPLAY statement somewhere in your real code.
The reported error simply means that that DISPLAY format is not wide enough for the data. By default DISPLAY will use whatever format you specified in the definition of a data element. If you did not specify anything then every datatype also has a default. For decimals the default is "->>,>>>.99".
You can either increase the format in the definition or override it in the display statement like so:
display tt_data.DateTime format ">>>>>>>>>>>>>>>9".
Note: the display format has no influence on the values that you can store in a field. You can always "overstuff" more data into a variable than you can display. The format is only for output display purposes -- it has nothing to do with storage.
The assignment works fine, however the display not.
So ...
DISPLAY tt_data.DateTime.
... does not work because it uses format "->>,>>9.99".
You can change the format in the definition, for example "99999999999999", or do:
DISPLAY tt_data.DateTime FORMAT "99999999999999".
I have written the program to show all the data on window but stuck in the case for showi a single record with comma(,) in drop down box. Let me share codes what i tried.
DEFINE TEMP-TABLE tt_seq_report
FIELD npai_output_expression AS CHARACTER FORMAT "X(50)".
/* Followings are written inside the drop down box using progress app builder */
/* ON VALUE CHANGED OF coCombo-4 Part Type(Label Name) */
DO:
DEFINE VARIABLE cPartTyp AS CHARACTER NO-UNDO.
CREATE tt_seq_report.
ASSIGN
tt_seq_report.npai_attribute_expression = "22+++,56-".
coCombo-4:ADD-LAST(tt_seq_report.npai_attribute_expression).
END.
When I run the window and select the drop down box then i can see the value upto before comma(,) i.e 22+++ but it should show the full value like 22+++,56-. May I get any help regarding this?
You can set the combo-box'es DELIMITER property to any other character. Comma is just a default.
"Delimiter character can have any ASCII value from 1 to 127. The default delimiter is a comma."