How do I loop excel sheet names inside quotes in GAMS 'GDXXRW? - gams-math

I would like to define a string set in GAMS to loop to read different xlsx sheet names in gdxxrw. However, I didn't find the appropriate code in the help documentation using string formatting and String Substitution as keywords.
'''
SET
sheets /index1, index2, index3/
B /a, b, c/
;
PARAMETER
POP0(B)
POP(B)
;
LOOP(sheets,
* Write Excel data to GDX
put_utility 'exec' / 'gdxxrw.exe Input.xlsx se=0 index='sheets.tl'!a1';
$Load POP0
POP(B)=POP0(B);
execute_unload "Output.gdx"
POP
* Write GDX data to excel
put_utility 'exec' / 'gdxxrw.exe RESULT.gdx o=RESULT.xlsx index='sheets.tl'!a7';
'''
I read loop in GAMS for scenario generation in excel. But GAMS report error as that
'''
116 Label is unknown
141 Symbol declared but no values have been assigned. Check for missing
data definition, assignment, data loading or implicit assignment
via a solve statement.
A wild shot: You may have spurious commas in the explanatory
text of a declaration. Check symbol reference list.
300 Remaining errors not printed for this line
352 Set has not been initialized
353 The domain for this index position is unknown and the element
cannot be checked at this point. Missing data statement.
502 GDXIN file not open - ignore rest of line
509 Dollar control statements are processed during compilation
and NOT during execution. The use of dollar statements
that change data may be misleading when inside a LOOP
or IF statement.
'''
I think the key is the apply of $Load or $loaddc. Does GAMS have a string formatting method control index sheet in quotes?

After a night of debugging, I finally solved the problem.
'''
SET
sheets /index1, index2, index3/
B /a, b, c/
;
PARAMETER
POP0(B)
POP(B)
;
LOOP(sheets,
* Write Excel data to GDX
put_utility 'exec' / 'gdxxrw.exe Input.xlsx se=0 index='sheets.tl:0'!a1';
*":0" is needed
* Load data from GDX (substitution of $load)
execute_load 'data.gdx',
POP0
;
POP(B)=POP0(B);
* Load data from GDX
execute_unload "Output.gdx",
POP
;
* Write GDX data to excel
put_utility 'exec' / 'gdxxrw.exe RESULT.gdx o=RESULT.xlsx index='sheets.tl:0'!a7';
'''
Very thank Lutz!

Related

include a txt file in GAMS - errors 140 & 36 in the first lines of my txt file

I am a new user in GAMS and I am trying to include a txt file in my code, but I get the same errors (error 140 & error 36) in the first lines of my txt file again and again.
Could anyone help?
My code goes like this, and I have also attached the txt file
* define the set of asset classes
set n Number of returns /n1*n120/;
* define Tables, Parameters, Scalars
Scalar T /120/;
$INCLUDE prices.txt
Please note, that later in the code I need to use the data from the text file in an equation like this:
EQ1.. sum(n, p(n)*prices(n)) =e= price0*exp(r*time);
Thanks
prices.txt file
Your prices.txt does not contain valid GAMS syntax. What you need is something like this:
Parameter prices(n) /
n1 455.5
n2 44545.5
/;

To grep contents from a CSV/Text File using Autohotkey(AHK) Script

Can anyone please help me in writing a script in AHK based on below requirement.
Requirement:
I have a CSV/TXT file in my windows environment which contains 20,000+ records in below format.
So, when I run the script it should prompt a InputBox to enter an instance name.
Example : If i enter Instance4 , it should display result in MsgBox as ServerName4
Sample Format:
ServerName1,ServerIP,Instance1,Type
ServerName2,ServerIP,Instance2,Type
ServerName3,ServerIP,Instance3,Type
ServerName4,ServerIP,Instance4,Type
ServerName5,ServerIP,Instance5,Type
.
.
.
Also as the CSV/TXT file contains large no of records , pls also consider the best way to avoid delay in fetching the results.
Please post your code, or at least show what you've already done.
You can use a Parsing Loop with CSV as the delimiter, and make a variable for each 'Instance' who's value is that of the current row's 'ServerName'.
The steps are to first FileRead the data from the file, then Loop, Parse like so:
Loop, Parse, data, CSV
{
; Parses row by row, then column by column in each row.
; A_LoopField // Current value
; A_Index // Current loop's index
; Write a script that makes a variable named with the current value of column 3, and give it the value of column 1
}
After that, you can make a Goto loop that spams InputBox and following a command that prints out the needed variable using the MsgBox command, like so:
MsgBox % %input%

using macro variable to read folder content in SAS 9.4 [duplicate]

This question already has answers here:
Why won't my macro variable resolve?
(2 answers)
Closed 5 years ago.
I'm trying to get the list of files in a directory with a SAS macro that uses a macro variable to specify dynamically the folder name. The code I run is the following:
%macro veicolo(codice_veicolo);
filename pipedir pipe ' dir "some_path\&codice_veicolo" /S' lrecl=5000;
data &codice_veicolo;
infile pipedir truncover;
input line $char1000.;
length directory $1000;
retain directory;
if line =' ' or
index(upcase(line),'<DIR>') or
left(upcase(line))=:'VOLUME' then
delete;
if left(upcase(line))=:'DIRECTORY OF' then
directory=left(substr(line,index(upcase(line),'DIRECTORY OF')+12));
if left(upcase(line))=:'DIRECTORY OF' then
delete;
if input(substr(line,1,10),?? mmddyy10.) = . then
substr(line,1,10)='12/31/2999';
date=input(substr(line,1,10),?? mmddyy10.);
format date mmddyy10.;
run;
proc sort data=&codice_veicolo;
by directory descending date;
run;
data folder_&codice_veicolo(drop=i line);
set &codice_veicolo;
by directory;
length filename $75;
retain number_of_files_in_directory directory_size;
if first.directory then
do;
number_of_files_in_directory=input(scan(line,2,' '),32.);
call symput(nfiles,number_of_files_in_directory);
directory_size=input(scan(line,4,' '),comma32.);
end;
file_size=input(scan(line,3,' '),comma32.);
filename=' ';
do i=4 to 100;
filename=trim(left(filename))||' '||scan(line,i,' ');
if scan(line,i,' ')=' ' then
leave;
end;
if index(upcase(line),'FILE(S)') then
delete;
if date ge '30DEC2999'd then
delete;
run;
%mend;
When I then execute the macro with the argument codice_veicolo being the name of the folder I want to search in, I get the following error:
Output Err std:
The system cannot find the path specified.
NOTE: 20 records were read from the infile PIPEDIR.
The minimum record length was 0.
The maximum record length was 90.
NOTE: The data set WORK.JL6AME1A6FK000442 has 2 observations and 3 variables.
NOTE: DATA statement used (Total process time):
real time 0.05 seconds
cpu time 0.01 seconds
I supposed that for some reason it could not resolve the macro variable, but if I run:
%let pgmpath = %sysfunc(pathname(pipedir));
%put &pgmpath;
I get the proper path and the proper directory, therefore I assume the problem is in the infile statement. The code runs fine without using macro variables.
I am using SAS 9.4 on Windows 8. Any ideas??
Thank you in advance :)
Luca
Macro variable references are not expanded inside of single quotes.
Try this instead.
filename pipedir pipe %sysfunc(quote(dir /s "some_path\&codice_veicolo")) lrecl=5000;

How to run same syntax on multiple spss files

I have 24 spss files in .sav format in a single folder. All these files have the same structure. I want to run the same syntax on all these files. Is it possible to write a code in spss for this?
You can use the SPSSINC PROCESS FILES user submitted command to do this or write your own macro. So first lets create some very simple fake data to work with.
*FILE HANDLE save /NAME = "Your Handle Here!".
*Creating some fake data.
DATA LIST FREE / X Y.
BEGIN DATA
1 2
3 4
END DATA.
DATASET NAME Test.
SAVE OUTFILE = "save\X1.sav".
SAVE OUTFILE = "save\X2.sav".
SAVE OUTFILE = "save\X3.sav".
EXECUTE.
*Creating a syntax file to call.
DO IF $casenum = 1.
PRINT OUTFILE = "save\TestProcess_SHOWN.sps" /"FREQ X Y.".
END IF.
EXECUTE.
Now we can use the SPSSINC PROCESS FILES command to specify the sav files in the folder and apply the TestProcess_SHOWN.sps syntax to each of those files.
*Now example calling the syntax.
SPSSINC PROCESS FILES INPUTDATA="save\X*.sav"
SYNTAX="save\TestProcess_SHOWN.sps"
OUTPUTDATADIR="save" CONTINUEONERROR=YES
VIEWERFILE= "save\Results.spv" CLOSEDATA=NO
MACRONAME="!JOB"
/MACRODEFS ITEMS.
Another (less advanced) way is to use the command INSERT. To do so, repeatedly GET each sav-file, run the syntax with INSERT, and sav the file. Probably something like this:
get 'file1.sav'.
insert file='syntax.sps'.
save outf='file1_v2.sav'.
dataset close all.
get 'file2.sav'.
insert file='syntax.sps'.
save outf='file2_v2.sav'.
etc etc.
Good luck!
If the Syntax you need to run is completely independent of the files then you can either use: INSERT FILE = 'Syntax.sps' or put the code in a macro e.g.
Define !Syntax ()
* Put Syntax here
!EndDefine.
You can then run either of these 'manually';
get file = 'file1.sav'.
insert file='syntax.sps'.
save outfile ='file1_v2.sav'.
Or
get file = 'file1.sav'.
!Syntax.
save outfile ='file1_v2.sav'.
Or if the files follow a reasonably strict naming structure you can embed either of the above in a simple bit of python;
Begin Program.
imports spss
for i in range(0, 24 + 1):
syntax = "get file = 'file" + str(i) + ".sav.\n"
syntax += "insert file='syntax.sps'.\n"
syntax += "save outfile ='file1_v2.sav'.\n"
print syntax
spss.Submit(syntax)
End Program.

How do we print characters line by line and save it to csv or text file in PLSQL

DECLARE
V_NUMBER NUMBER :=23;
BEGIN
LOOP
V_NUMBER:=V_NUMBER+1;
EXIT WHEN V_NUMBER:=25;
--Some kind of function to be applied for printing and nesting lines into CSV or TEXT file.
END LOOP;
COMMIT;
END;
Scripting an Oracle SQL Query for Creating a CSV or Text Typed File Output
Consider running this from a SQL Plus session and use the SPOOL command. All output of the SQL command that follows will be written to the file name you specify.
If you need to append your results each successive time the SQL commands are run, then an OS level command would work appropriately when invoking this sqlplus executable block of PL/SQL:
Where the file name of this script is: "sample_csv_out.sql"
DECLARE
v_total_columns constant number:= 3; -- Number of columns queried
v_column_counter number;
v_csv_record varchar2(1000);
c_csv_column_format constant varchar2(15):=
'<<COLUMN1_VAL>>,<<COLUMN2_VAL>>,<<COLUMN3_VAL>>';
cursor result_cur is
SELECT column1, column2, column3
FROM tablea
WHERE column1 = ... ;
BEGIN
v_csv_record:= 'COLUMN1,COLUMN2,COLUMN3';
dbms_output.put_line (v_csv_record);
FOR i in result_cur LOOP
v_csv_record:= replace(c_csv_column_format, '<<COLUMN1_VAL>>', i.column1);
v_csv_record:= replace(v_csv_record, '<<COLUMN2_VAL>>', i.column2);
v_csv_record:= replace(c_csv_record, '<<COLUMN3_VAL>>', i.column3);
dbms_output.put_line(v_csv_record);
END LOOP;
END;
So, for example in a WINDOWS O/S environment, the call to append the output to a specific file name would be:
C:\> sqlplus sample_csv_out.sql >> mycsv_out.csv
The >> notation instructs the operating system to pipe the output of running sample_csv_out.sql via a sqlplus session.
The command DBMS_OUTPUT does the rest. If you need more details, see more Oracle documentation on DBMS_OUTPUT.
COMMENTS: I chose the RECORD STRING TEMPLATE approach to make this script a little more flexible and reusable. I recommend to keep any data manipulation logic within the CURSOR statement. Often when the two are mixed, it gets harder to debug any typos in syntax within a long string of values.
The construction of an output record was also designed to reduce typos, mistakes and frustration... if there are more than 3 columns in your own scripts, adding another element to the output string is mostly a cut-and-paste operation. Likewise with the "header" row (column titles).
You can read and write files in PL/SQL using the UTIL_FILE package
http://docs.oracle.com/cd/B19306_01/appdev.102/b14258/u_file.htm