File output is not as expected - ms-access

The following piece of code is giving unexpected results, but very rarely. It works about 99% of the time. It should be outputting an XML file.
Open XMLPath & dblFoo & ".xml" For Output As #15
Print #15, "<?xml version=" & Q & "1.0" & Q & " encoding=" & Q & "utf-8" & Q & "?>"
Print #15, "<main>"
Print #15, "<general>"
Print #15, "<foo>BAR</foo>"
Print #15, "</general>"
Print #15, "<foobar_entry>"
Print #15, "<bar_name>" & Replace(dblFoo, ".", "_") & "_" & someOtherVal & "_F0" & "</bar_name>"
`
` some more tag printing
`
Print #15, "</foobar_entry>"
Print #15, "</main>"
Close #15
Now, the 'bad part' of the output XML file will look like this:
</general>
try>
... rest of file looks normal
In this case the first part of <foobar_entry> has been cut off.
Another error it will show is:
</main>
NUL NUL NUL NUL NUL NUL NUL NUL NUL NUL NUL NUL NUL NUL NUL NUL NUL NUL NUL NUL NUL NUL NUL NUL
Where NUL is ASCII code 0.
Could garbage data be output to the file that would move the current read/write position in the file?
Is this just a matter of two people calling the function at the same time? It is an Access application after all, with many users on the system.
There doesn't seem be any error checking code when writing to the file or opening the file.

I strongly recommend not using Print if you want reliable output in files. Access's text mode printing is known to cause trouble, since it includes a lot of logic to do things like concatenating variables and writing non-text variables to CSV.
Instead, use binary writing to be in control of what actually gets written to the file.
Open XMLPath & dblFoo & ".xml" For Binary Access Write As #15
Put #15, , "<?xml version=" & Q & "1.0" & Q & " encoding=" & Q & "utf-8" & Q & "?>" & vbCrLf
Put #15, ,"<main>" & vbCrLf
'Etc
Close #15
Also note that this is low-level file IO, that means, each write statement is sent to the disk without buffering. I strongly recommend writing the whole string at once, and not using tons of little Print/Put statements. Else, performance will suffer, especially on network drives.
Note that you specify encoding=utf-8 in your XML file, but you're certainly not encoding it as UTF-8 if you're writing it to a file this way, though.

Related

How would a date in HTML file using a .bat script

I have a .html file titlepage.html that contains the following line:
<span class="titlepage modified">Modified: Feb 13, 2020 </span>
The problem is, that sometimes I forget to change the "Modified: " date
I run a .bat file which moves this titlepage.html to the proper location, so I figured it would make sense to add a subroutine in the .bat file to update the date before moving it.
my current .bat file looks like:
#echo off
setlocal enabledelayedexpansion
set infile=titlepage.html
set outfile=result.html
Set find=Modified:
set replace="<span class="titlepage modified">Modified: %DATE% </span>"
del result.html
for /F "tokens=1,2 delims=" %%n in (!infile!) do (
set LINE=%%n
set TMPR=!LINE:%find%=%replace%!
echo !TMPR!>>%outfile%
)
And the line in question of my looks like:
<span class="titlepage modified">"<span class="titlepage modified">Modified: 04/10/20 </span>" Feb 13, 2020 </span>
So it successfully inputs the information I want, but I need it to replace the entire line in question not just the part I used for the lookup.
*Note the dates will be arbitrary so I can't perform a lookup on the entire line.
So I want to:
1. Lookup for a line containing a string
2. Replace that entire line with my new input.
Thanks in advance.
#echo off
setlocal enabledelayedexpansion
set "target=./titlepage.html"
set "destination=./titlepage.html"
set "find=(?mi)^.*Modified:.*$"
set "replace=<span class=\"titlepage modified\">Modified: %DATE% </span>"
powershell -noprofile -command^
$content=get-content -path '!target!';^
$result=$content -replace '!find!', '!replace!';^
set-content -path '!destination!' -value $result
powershell reads the the target ./titlepage.html, does the replacement and writes to the destination ./titlepage.html.
The regular expression pattern searches for Modified: in a line. The find variable contains the pattern and uses options (?mi). The m is multiline mode and the i is case insensitive. If you want case insensitive, remove the i.
Regular expression pattern:
(?mi) Regular expression options. m is multiline and i is case insensitive.
^ By default, the match must start at the beginning of the string; in multiline mode, it must start at the beginning of the line.
. Wildcard: Matches any single character except \n.
* Matches the previous element zero or more times.
$ By default, the match must occur at the end of the string or before \n at the end of the string; in multiline mode, it must occur before the end of the line or before \n at the end of the line.
Replacement string:
\" Escape nested double quote for command line parsing to powershell.
View the Regular Expression Language - Quick Reference for more information.
The ^ at the end of lines, of the powershell command, are line continuations.

escaping "\" in the end of a string in tcl

I want to create a string that ends with "\". For example:
set str {",$"23"^##$\'"\}
This won't work because tcl thinks that I'm escaping the "}" here.
So I tried to escape the "\"
set str {",$"23"^##$\'"\\}
but now the value of str is ",$"23"^##$\'"\\.
I want the value of str to be with one "\" in the end: ",$"23"^##$\'"\
How can I do that while creating the string inside {}
The easiest way I could think is to use format:
puts [format {",$"23"^##$\'"%s} \\]
",$"23"^##$\'"\
I think you could even try with the %c and the ascii code of the \.
You can't; this is one of the small number of cases that can't be quoted that way. Here's the proof from an interactive session:
% gets stdin s
",$"23"^##$\'"\
15
% list $s
\",\$\"23\"^##\$\\'\"\\
Other such cases are thing like where there's unbalanced braces, and so on. They really don't come up very often. That backslash form above generated by list is the alternative (and you can put it in double quotes if you wish).

how to remove a text before a character or string on a CSV file using batch

I have a CSV file that I want to modify using batch to remove a string basically I have the next
randomID1, randomID2, randomID3, networkinterface, othercolumn1, othercolumn2,
abc123AAB, 098189909, 999181818, net on Server123, FORCED, anotherthing,
abc2455aB, 848449388, 123131232, LocalNet on SEV1, FORCED, otherlessstuff,
My relevant caracthers are Server123 and SEV1, so I need to convert the above on
randomID1, randomID2, randomID3, networkinterface, othercolumn1, othercolumn2,
abc123AAB, 098189909, 999181818, Server123, FORCED, anotherthing,
abc2455aB, 848449388, 123131232, SEV1, FORCED, otherlessstuff,
This means removing 'net on ' and 'LocalNet on ' strings.
How can I do this?
Batch language is far from ideal for this, but here's a basic script to simply line-by-line remove occurrences of "net on " and "LocalNet on " from input.txt and save the result as output.txt:
#ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
TYPE NUL > output.txt
FOR /F "delims=" %%L IN (input.txt) DO (
SET LINE=%%L
SET LINE=!LINE:LocalNet on =!
ECHO/!LINE:net on =!>> output.txt
)
Refinements are possible and may be needed. E.g., this won't work if the file contains reserved characters such as &. And it's not case sensitive. The latter is the reason the "LocalNet on " substitution is done before the "net on " substitution which is a substring when case insensitive. There's nothing CSV specific here because from your question that doesn't appear to be required. But if for example you needed to treat different comma-separated tokens differently, that can be done with a "delims=," option and some extra code.

Ruby 2.0 CSV reader treating Microsoft Excel generated CSV files differently and not stripping control characters

PROBLEM: Ruby 2.0 CSV reader on Mac Mavericks treats Microsoft Excel generated CSV files that have embedded HTML differently. Works fine on Ruby 1.8 with FasterCSV.
I just upgraded my Mac to Mavericks (OS X 10.9.4) and also upgraded Ruby to 2.0.0p451 (I used to use Ruby 1.8+ with the FasterCSV gem but now use Ruby 2.0+ with it's native CSV.)
Ruby Version:
ruby -v
ruby 2.0.0p451 (2014-02-24 revision 45167) [universal.x86_64-darwin13]
The CSV file is generated from Office 2011, saved from an original ".xlsx" file.
The following HTML is contained in a single cell of the Microsoft .xlsx file BEFORE it is saved as CSV...
<h1 style="text-align:center; font: bold 1.5em Arial;">This is the Title</h1>
<p style="text-align:center;"><img style="width:300px; height:100px" src="./IMAGES/MAIN/image1.png" alt="Image 1"/></p>
<p style="text-align:center;">This is a sentence.</p>
There are other cells, that also have HTML code embedded.
To reproduce...
Open an Excel worksheet
Copy the above HTML into cell A1 (ensure that there are Mac carriage returns control+command+return between HTML constructs (e.g. between the end of the "h1" construct and the start of a new "p" construct, in order to ensure line breaks between all complete HTML constructs, right in the Excel cells.
Copy what in cell A1 to cell A2, directly below cell A1, to ensure multiple CSV rows (your file will have two formal CSV rows).
First save the file as an xlsx file (e.g. "file.xlsx")
Then save the worksheet as a CSV file (e.g. "file.csv").
You will now have an Excel generated CSV file that has two formal CSV rows, where each row will have multiple HTML constructs that are separated by line feeds, within it.
Reading the CSV File...
I use the following code to read CSV file and print the contents of each cell, both before and after I try to strip control characters...
arrayOfHtmlConstructs = CSV.read( file.csv )
arrayOfHtmlConstructs.each_with_index do | construct, i|
output = "" << construct.to_s
puts "BEFORE: " << output
output = output.gsub(/\r/, "") # Replace Microsoft carriage returns FAILS!
output = output.gsub(/\\"/, "\"") # Replace escaped quotes with quotes WORKS FINE!
output = output.gsub(/\[\"/, "") # Remove prefix [" WORKS FINE!
output = output.gsub(/\"\]/, "") # Remove suffix "] WORKS FINE!
puts "AFTER: " << output
end
Before trying to strip code, the CSV string "output" looks as follows...
BEFORE: ["<h1 style=\"text-align:center; font: bold 1.5em Arial;\">This is the Title</h1>\r<p style=\"text-align:center;\"><img style=\"width:300px; height:100px\" src=\"./IMAGES/MAIN/image1.png\" alt=\"Image 1\"/></p>\r<p style=\"text-align:center;\">This is a sentence.</p>"]
You'll notice that it includes [" at the beginning and ]" at the end, along with escaped quotes and embedded carriage returns /r
PROBLEM: All of the gsub statements work except for the one that tries to replace all carriage returns with blanks.
After running the Ruby script, the string "output" looks as follows, where everything gets substituted properly, except for the carriage returns...
AFTER: <h1 style="text-align:center; font: bold 1.5em Arial;">This is the Title</h1>\r<p style="text-align:center;"><img style="width:300px; height:100px" src="./IMAGES/MAIN/image1.png" alt="Image 1"/></p>\r<p style="text-align:center;">This is a sentence.</p>
For some reason, the carriage returns are NOT being replaced/substituted.
Also, before I upgraded to Ruby 2.0, I used to use FasterCSV and none of the substitution statements were needed. Everything just worked.
Any thoughts as to why this is all happening and how to properly handle it? Any assistance is greatly appreciated.
The scope of my answer has changed so I've edited down to just the RegEx as that seems to be more on topic.
I've updated my expression to cover all of your substitutions, simply update with this block of code:
arrayOfHtmlConstructs.each_with_index do | construct, i|
output = "" << construct.to_s
puts "BEFORE: " << output
output = output.gsub(/\\"/, "\"") # Replace escaped quotes with quotes WORKS FINE!
output = output.gsub(/(\\r|\[|\])/, "")
puts "AFTER: " << output
end
Try this:
#csv = CSV.read(params[:file].path, headers: true, skip_blanks: true, encoding:'windows-1256:utf-8')
You need to do the Microsoft CSV encoding

How can you convert LF's to CRLF in a text file using a vbscript?

I have a CSV file that gets generated by a Mac program (unfortunately, with little encoding flexibility) which writes LFs at the end of lines. Then a vbscript reads this file like so:
Set objTextFile = fso.OpenTextFile("the_file.csv", 1)
lineItemString = objTextFile.Readline
However, since it is looking for CRLF at the end of the lines, lineItemString contains the text of the entire file. Since this is a daily procedure, I'd like not to have to add an interim step of using some utility program that properly converts all the line endings to CRLF.
Is there a way to avoid this by doing this conversion from within my vbscript?
Thanks in advance!
This will replace each LF in a string with CRLF:
Replace(str, vbLf, vbCrLf)
Depending on how you want to process the file it might be easier to just read the entire file and split the content by vbLf, though.
Set objTextFile = fso.OpenTextFile("the_file.csv", 1)
For Each line In Split(objTextFile.ReadAll, vbLf)
' do stuff
Next