Way of checking if a bookmark exists from SAS using DDE connection to Word - ms-word

I am using SAS v9.4, running a DDE connection to Word 2010.
Once I have connected to a word document, I would like to be able to check from withing SAS whether a specific bookmark exists or not. Is this possible withing the DDE framework?
I have tried adding the if statement, but it looks like the command Bookmarks.Exist isn't recognised.
filename sas2word dde 'winword|system';
data _null_;
file sas2word;
if put '[Bookmarks.Exists("Bkm1")]' then do;
put '[EditGoTo.Destination = "Bkm1"]';
put '[Insert "Test"]';
end;
run;
But it just crashes and comes up with.
"The Bookmark does not exist"
Is there a way to query the Word document so we can avoid the pop-up/crash? Or, if not, is there a way to run a try-catch loop within the code so it keeps running?
Also sorry if the tags are not accurate, wasn't sure exactly what this question fell under so I tagged all three options - feel free to edit if inappropriate.

Related

How to replace value in txt file with powershell from GitHub

I want to build a simple script that may be useful for others as well, but I have only very basic programming knowledge and can't do it myself without learning how to write powershell scripts from scratch.
What this script is supposed to do is, open an INI file (really just a txt), look for a variable with an assigned value and replace that value from a txt hosted on GitHub, save and then run a program.
This is for the tracker list of qBittorrent, since that feature still hasn't been implemented and the only other script that I could find that does this is for linux and mac, there seem to be none for windows.
The basic idea is this:
get-content "c:\users\[user]\appdata\roaming\qbittorrent\qbittorrent.ini"
# This is where pseudo code starts
get file from "[github-link.txt]"
save file to cache # keeping it is useless as it gets updated daily
find variable "Session\AdditionalTrackers=" in qbittorrent.ini
replace value of variable with content of cached file # this is what I struggle with most when looking for example code. Everything I could find specified the exact string that needed replacing, which in this case is quite long and may change with every update of the file.
overwrite original file
launch program qbittorrent.exe
end script
Conveniently or most likely deliberately all (most) of the tracker lists on GitHub are already formatted in a way that they can be directly pasted into the file without having to worry about formatting. Example.
I can totally understand if nobody wants to do the work, but I would greatly appreciate it and possibly others that are looking for a stopgap for the lacking feature.
If this already exists, go ahead and call me an idiot and while you're at it drop a link ;)
I just found a little tool called Power Automate and it pretty much does what I was looking for. It's not quite as elegant as a single click script but it does the job. Sadly I can't share the "flow" I built because, well, there is no option for it - thanks Microsoft. So, I'll try my best to write it out.
Not quite a "solution" but pretty to close to it.
Here is the "flow":
get file from web // from github for example
read text from file // read downloaded .txt file
read text from file // read qBittorrent.ini
crop text // crop between flags in qBittorrent.ini use "Session\AdditionalTrackers=" as start and "Session\GlobalMaxRatio=" as end and save to cropVar2
crop text // crop before flag use "Session\AdditionalTrackers=" as flag and save to cropVar1
crop text // crop after flag use cropVar2 as flag and save to cropVar3
replace text // replace cropVar2 with content of downloaded file and save to cropVar2
write text to file // write cropVar1,cropVar2,cropVar3
end flow
Keep in mind that any changes to the qBittorrent.ini may change the order of the entries. Which means you have to check if it's still correct after every update and after every change you make in the options. This is a massive cludge after all...
You can input fail saves so that you won't break anything if the order changed.

Use SQL Workbench to read a variable from a file

UPDATE: in the workbench/J log file I am seeing this error:
ERROR Variable names may only contain characters (a-z, A-Z), numbers and underscores
I'm sure this is what is causing my process to fail, but I have no idea why because my variables are named appropriately. I've tried renaming them a few times just in case and the same thing happens.
ORIGINAL POST:
I am working on an automated process to dump the contents of a Postgres query to a text file and FTP it to someone. The process I have been using successfully is a windows batch script that runs SQL Workbench to run the query and write the entire contents of the table to a text file and FTP it.
Now I want to be able to use WBVarDef to load a variable from a text file and use it in my query. For reference, the variable is the unique id of the last record that was FTPed. This is the code i have:
WBVarDef -variable=id -contentFile=id.txt;
WBVardef today=#"select to_char(current_date,'mmddyyyy')";
WBExport -type=text
-file='c:/CLP/FTP/$[today]circ_trans.txt'
-delimiter='|'
-quoteAlways=true
-lineEnding=crlf
-encoding=utf8;
SELECT
*
FROM
transactions
WHERE
transactions.id > $[id]
ORDER BY
transactions.id;
The only thing new here is the reference to the text file that contains the id on the first line. This completely breaks the process but as far as I can tell, I am using this according to the SQL Workbench documentation.
Any help would be greatly appreciated.
I have figured this one out. I was running an older version of workbench that did not support this functionality. Now that I upgraded to build 119 this is working. I'm having other issues but that's a different story....

ESS[SAS] Submit region not working as expected -- each submission starts a new session

Specs: SAS 9.3, GNU emacs 23.4.1 (2012-06-05), and what I think is kind of an old version of ESS (sometime in 2001 maybe?). Unix -- I think SunOS 5.10.
I'm a fairly new emacs user and a very new user of ESS[SAS]. I have noticed that code which works when submitted as an entire file will not work when I submit it region by region. Here is an example:
libname mylib "/.";
data temp; set mylib.temp; run;
Assume that I have a directory as specified in libname and there is a SAS dataset called temp in it -- my code works properly when I submit the whole thing, but if I run just the first line and then the second, it tells me that "mylib" is not defined.
Based on the behavior of the log files -- the second submission creates a log file that overwrites the first -- I think what is going on is that it's starting a new SAS session with each submission. Why might it be doing this? (ESS does not do that with R code -- I can run a snippet to define a variable and then that variable stays defined.) I find I make fewer programming errors if I test things incrementally rather than running all my code in batch mode, and the GUI for SAS in unix leaves something to be desired, so I would really like to find a fix to this.
The only other clue I have is a pair of warnings I get on every submission:
NOTE: Unable to open SASUSER.REGSTRY. WORK.REGSTRY will be opened
instead.
NOTE: All registry changes will be lost at the end of the session.
WARNING: Unable to copy SASUSER registry to WORK registry. Because of
this,you will not see registry customizations during this session.
NOTE: Unable to open SASUSER.PROFILE. WORK.PROFILE will be opened
instead.
NOTE: All profile changes will be lost at the end of the session.
I googled those warnings separately and found they're commonly associated with a corrupt profile, but unfortunately the recommended fix did not fix anything (after deleting the iffy profile, it just restored itself and the error persisted). I am not sure whether this is related or not.
I realize this question might be out of scope for stackoverflow; if it is, a redirect to a more appropriate forum would be much appreciated.

Is there a way to attach a file (.txt) in calc open office programmatically (using macro)?

I have a .txt file that I need to attach in a column of my sheet, and i have the path to this file.
So I need to read this path and attach the file in another column programmatically. Is there a way to do it?
thanks in advance.
Indeed there is! And using by using macros it is quite easy to do.
Enabling macros
Go to the Tools > Options menu and click on the Security section under OpenOffice.org. Once there, click the Macro Security button. Now on the Security Level Tab, make sure that your settings will allow you to run Macros.
My settings are on low because I'm the author of all the macros I run, if you are not sure that this will be your case you might want to use a higher setting.
Note: Be careful, if you are unlucky or live in the 90's an evil macro can cause serious damage!
Creating a new macro
Now that you can run them, you must create a new macro. OpenOffice accepts a wide range of languages including Python, but since you didn't specified any I'll use OO's version of basic here.
Go to Tools > Macros > Organize Macros > OpenOffice.org Basic, and once there add a new module under your file's tree. Give it a meaningful name.
The actual macro
Once you create a new module the editor screen will pop up, write this code below:
Sub DataFromFile
Dim FileNo As Integer
Dim CurrentLine As String
Dim File As String
Dim Msg as String
Dim I as Integer
' Get the filename from the cell, in this case B1.
currentSheet=ThisComponent.CurrentController.ActiveSheet
fileName = currentSheet.getCellRangeByName("B1").getString
' Create a new file handler and open it for reading
FileNo = FreeFile
Open fileName For Input As #FileNo
I = 0
' Read file until EOF is reached
Do While not eof(FileNo)
' Read line
Line Input #FileNo, CurrentLine
' Define the range to put the data in as A4:A999 '
curentCell = currentSheet.getCellRangeByName("A4:A999").getCellByPosition(0,I)
' Select the I-th cell on the defined range and put a line of the file there
curentCell.String = CurrentLine
'Increase I by one
I = I + 1
Loop
Close #FileNo
End Sub
To test it, just create a text file and put something in it, then put the path to it on cell B1 and run the macro. You can run the macro in many ways, for test purposes just use the Run button on the same window that you used to create the module. This is the expected result:
Note: If you are unfamiliar with linux, don't be intimidated by that file path, it's just how they are on linux. This would just work the same with windows and it's file path structure.
Further improving the macro
I wrote the code above with the goal of making it as easy to understand as possible, therefore the macro have plenty of room for improvement, such as:
Being able to show the data retrieved on multiple columns/A single column/Something else
Once you have retrieved the data from the file, you can display it on your spreadsheet in nearly anyway you want it. Let me know if the way you initially intended was not addressed and I will edit the answer.
Having to re-run the macro every time you want the data updated.
This is easily fixed. There are many ways to automatize the macro execution, the one I'm most familiar with consists on making it run on a loop in conjunction with a delay of, say, 5 seconds and making it start as soon as the file loads.
Sub Main
Do While True
DataFromFile()
Wait(5000)
Loop
End Sub
And from now on you should call the Main sub instead of the DataFromFile.
To make the macro run at start-up go to Tools > Customize on the Events tab and select Open Document from the list then click on the Macro button. On the dialog to select the macro, pick Main. Now close the document, reopen it, and voila!
Using Cell Ranges
It's easier to keep your code and make changes to it if you name the cell ranges and use their names instead of their absolute address. To name a range (or a single cell) you must first select it then click on Data > Define Range to give it a name, for example B1 could be called 'FilePath' and A4:A999 could be called 'DataRange'. This way if you ever need to change them, you don't have to change the macro, just the defined range name.
Don't forget to update the code to look for the range instead of the address, for example, this bit of code:
getCellRangeByName("A4:A999")
would be rewritten to
getCellRangeByName("DataRange")
Error checking
It is a good idea to check and deal with error or unexpected events. What if the file doesn't exists? What if it is bigger than the defined range?
Further reading
Official reference regarding files for OpenOffice Basic macros.
A guide on different ways to run a macro
A great introduction to macro programming

Disabling the PostgreSQL 8.4 tsvector parser's `file` token type

I have some documents that contain sequences such as radio/tested that I would like to return hits in queries like
select * from doc
where to_tsvector('english',body) ## to_tsvector('english','radio')
Unfortunately, the default parser takes radio/tested as a file token (despite being in a Windows environment), so it doesn't match the above query. When I run ts_debug on it, that's when I see that it's being recognized as a file, and the lexeme ends up being radio/tested rather than the two lexemes radio and test.
Is there any way to configure the parser not to look for file tokens? I tried
ALTER TEXT SEARCH CONFIGURATION public.english
DROP MAPPING FOR file;
...but it didn't change the output of ts_debug. If there's some way of disabling file, or at least having it recognize both file and all the words that it thinks make up the directory names along the way, or if there's a way to get it to treat slashes as hyphens or spaces (without the performance hit of regexp_replaceing them myself) that would be really helpful.
I think the only way to do what you want is to create your own parser :-( Copy wparser_def.c to a new file, remove from the parse tables (actionTPS_Base and the ones following it) the entries that relate to files (TPS_InFileFirst, TPS_InFileNext etc), and you should be set. I think the main difficulty is making the module conform to PostgreSQL's C idiom (PG_FUNCTION_INFO_V1 and so on). Have a look at contrib/test_parser/ for an example.