I must create a text file with ANSI encoding using vbs.
If I just create it, without to write any text, using this code...
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set ObjFileTxt = objFSO.objFSO.CreateTextFile("filename.txt", True, False)
Set ObjFileTxt = nothing
Set objFSO = nothing
... I get an ANSI text file, but if I try to write some text, for example...
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set ObjFileTxt = objFSO.CreateTextFile("filename.txt", True, False)
ObjFileTxt.Write "ok"
Set ObjFileTxt = nothing
Set objFSO = nothing
... I get an UTF8 text file.
Any help?
It's not possible that the code you posted would create a UTF8-encoded output file. The CreateTextFile method supports only ANSI (windows-1252) and Unicode (little endian UTF-16) encodings.
The only ways to create UTF8-encoded files in VBScript are the ADODB.Stream object:
Set stream = CreateObject("ADODB.Stream")
stream.Open
stream.Type = 2 'text
stream.Position = 0
stream.Charset = "utf-8"
stream.WriteText "some text"
stream.SaveToFile "C:\path\to\your.txt", 2
stream.Close
or writing the individual bytes (including the BOM).
I know this is already old, but for future references...
Believe it or not, I had the same problem until I converted my VBS to ANSI (was UTF-8). Then, every new text file created with it was also ANSI and not UTF-8 any more.
Related
We have a server generated HTML file (myFile.html) that we embed in emails that get sent to our clients. We've been using this method for years with minimal issues. We use Windows Server 2012 with smtp server via II6. Recently the HTML is getting skewed in the email. When checking the source file, all looks well. Directly opening the HTML file for viewing in a browser works as you'd expect. Here is the code we're using to read the file into memory to prepare for emailing:
Set objFile = objFSO.OpenTextFile(strFilePath)
Do While objFile.AtEndOFStream <>True
line = objFile.ReadLine
If Instr(1, line, "<table") > 0 And strHeaderWritten = "N" Then
strHeaderWritten = "Y"
strFileContent=strFileContent & strHeader
End If
strFileContent=strFileContent & line
Loop
set objFile = Nothing
And then we add the content to the email and send:
strBody = strFileContent
Set objMail = CreateObject("CDO.Message")
Set objMail.Configuration = cdoConfig
objMail.From = strFrom
objMail.ReplyTo = strReplyTo
objMail.To = strTo
objMail.Subject = strSubject
objMail.HTMLBody = strBody
objMail.Fields("urn:schemas:httpmail:importance").Value = strImportance
objMail.Send
And here are examples of what it spits out in the email. There are no errors in the source:
Has anyone else had this happen to them?
Been toiling over this for hours looking for an explanation. Thank so much for reading!
I tried using the ADO Stream method for the email, but it is still coming out the same:
Dim objStream
Set objStream = Server.CreateObject("ADODB.Stream")
objStream.Type = 2 'adTypeText
objStream.CharSet = Application("CharacterSet")
objStream.Open
objStream.LoadFromFile strFilePath
Do While Not objStream.EOS
line = objStream.ReadText(-2)
If Instr(1, line, "<table") > 0 And strHeaderWritten = "N" Then
strHeaderWritten = "Y"
strFileContent=strFileContent & strHeader
End If
If Instr(1, line, "< table") > 0 Then
strFileContent=strFileContent & "<h3>Broken HTML</h3>"
End If
strFileContent=strFileContent & line
Loop
objStream.Close
Set objStream = Nothing
As you can see, I also added a check for one of the persistent errors I'm seeing where there has been a space inserted between < and table. Checking the output this way did not capture the issue as in checking the text for the added space. So it must be happening after it's been written or I need to use a regex for the test. I'll try that next. I'm still seeing it in multiple email clients. Here's an example post test of ADO Stream:
This seems to be a common problem in CDO. I've found a few references online to the problem that spaces are randomly inserted into the HTMLbody.
One answer was to make the HTML body not one long string, because CDO will then insert random spaces, but to include whitespace yourself, so that CDO doesn't have to.
You could try adding VbCrLf or just plain spaces in the text you're sending.
A second suggestion made more sense to me; this can be an encoding problem. That also explains why adding your own whitespace could be a workaround.
Anyway; CDO allows for setting the encoding of the CDO.Message object before sending.
Try objMail.BodyPart.ContentTransferEncoding = "quoted-printable" to see if that solves it.
The issue is windows use of both line break and carrage return. I recommend loading the body of the text and replacing all instances of vbcrlf with just vblf and you will find you wont have the double spacing anymore.
e.g.
body = replace(body, vbcrlf, vblf)
How can I show an nvarchar column that stores unicode data (Entered with the zawgyi1 font) in a classic ASP web page?
When I retrieve and write the value to the page, it shows "?????". I set my ASP page's content type of UTF-8 with the following meta tag:
<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
Unfortunately, the text is still rendered as "?????".
Any suggestions or ideas on how to display unicode values in a classic ASP page?
The Content-Type meta header informs the browser to treat the content sent as a UTF-8 encoded text stream. It doesn't ensure that the stream sent is actually UTF-8. To handle UTF-8 correctly you need to do 3 things:-
Ensure your static content is saved in a UTF-8 compatible encoding.
Ensure your dynamic content is encoded to UTF-8.
Inform the client that the content is UTF-8 encoded.
Item 1 requires either that you actually save the ASP file as a UTF-8 encoded file or that all your static content in the file is within the ASCII character range (0-127). Note if you save as UTF-8 then all your server-side script must use characters within the ASCII character range. In Visual Studio you can do so by "Saving the file AS..." and then clicking on the little arrow on the Save button.
Item 2 requires that the Response.CodePage property is set to the UTF-8 code page 65001, you can do this in code or by adding the attribute CODEPAGE=65001 to the <%# %> declarations on the first line of the ASP file. If you do it in code you must set it before any calls to Response.Write.
AND: do not use chr or asc functions (these are buggy when using 65001) but use chrw and ascw instead.
Item 3 requires that the Content-Type header contains the charset=UTF-8 qualifier. As you are already doing you can do this with the META header. Personally I find that to be a bit of kludge, I prefer to use Response.Charset = "UTF-8" in code. This places the qualifier on the true Content-Type HTTP header.
What about your codepage definition at the top of your page?
<%#LANGUAGE="VBSCRIPT" CODEPAGE="65001"%>
Here's a useful script to batch-convert ASP files from ANSI to UTF-8 encoding:
<HTML>
<HEAD>
<TITLE>ASP UTF-8 Converter - TFI 13/02/2015</TITLE>
</HEAD>
<BODY style='font-face:arial;font-size:11px'>
<%
Dim fso, folder, files, NewsFile, sFolder, objFSO, strFileIn, strFileOut
Set fso = CreateObject("Scripting.FileSystemObject")
sFolder = "C:\inetpub\wwwroot\sitefolder"
Function ANSItoUTF8( ANSIFile)
UFT8FileOut=ANSIFile&".utf8"
Set oFS = CreateObject( "Scripting.FileSystemObject" )
Set oFrom = CreateObject( "ADODB.Stream" )
sFFSpec = oFS.GetAbsolutePathName(ANSIFile)
Set oTo = CreateObject( "ADODB.Stream" )
sTFSpec = oFS.GetAbsolutePathName(UFT8FileOut)
oFrom.Type = 2 'adTypeText
oFrom.Charset = "Windows-1252"
oFrom.Open
oFrom.LoadFromFile sFFSpec
oTo.Type = 2 'adTypeText
oTo.Charset = "utf-8"
oTo.Open
oTo.WriteText oFrom.ReadText
oTo.SaveToFile sTFSpec,2
oFrom.Close
oTo.Close
oFS.DeleteFile sFFSpec
oFS.MoveFile sTFSpec,sFFSpec
End Function
ConvertFiles fso.GetFolder(sFolder), True
Function ConvertFiles(objFolder, bRecursive)
Dim objFile, objSubFolder
For each objFile in objFolder.Files
If Ucase(fso.GetExtensionName(objFile)) = "ASP" Then
ANSItoUTF8 objFile.path
response.write "• Converted <B>"&fso.GetAbsolutePathName(objFile)&"</B> from ANSI to UTF-8<BR>"
End If
Next
If bRecursive = true then
For each objSubFolder in objFolder.Subfolders
ConvertFiles objSubFolder, true
Next
End If
End Function
%>
</BODY>
</HTML>
First, I need to delete the top 4 rows from the sheet either before or after the conversion. There currently isn't anything in this script that will delete rows from the Excel file or from the CSV file that it creates.
Second, I'd prefer to pass the source and destination in this script rather then passing them later. Currently this script requires a command line to pass the source and destination it looks something like this.
C:\exceltocsv "source.xls" "destination.csv"
Instead of requiring source.xls and destination.csv to be provided as commandline arguments I'd rather have them resolved in the VBScript itself. Is this possible?
if WScript.Arguments.Count < 2 Then
WScript.Echo "Error! Please specify the source path and the destination. Usage: XlsToCsv SourcePath.xls Destination.csv"
Wscript.Quit
End If
Dim oExcel
Set oExcel = CreateObject("Excel.Application")
Dim oBook
Set oBook = oExcel.Workbooks.Open(Wscript.Arguments.Item(0))
oBook.SaveAs WScript.Arguments.Item(1), 6
oBook.Worksheets(2).Activate
oBook.Close False
oExcel.Quit
WScript.Echo "Done"
You can use the InputBox function to prompt for user input. Rows can be removed from an Excel worksheet via <range>.EntireRow.Delete.
Something like this should do what you want:
xls = InputBox("Enter source file.")
csv = InputBox("Enter destination file.")
Set oExcel = CreateObject("Excel.Application")
Set oBook = oExcel.Workbooks.Open(xls)
oBook.Sheets(1).Range("1:4").EntireRow.Delete
oBook.SaveAs csv, 6
oBook.Close False
oExcel.Quit
WScript.Echo "Done"
Edit: If you want hardcoded paths, simply define them as strings:
xls = "C:\path\to\input.xls"
csv = "C:\path\to\output.csv"
Set oExcel = CreateObject("Excel.Application")
Set oBook = oExcel.Workbooks.Open(xls)
oBook.Sheets(1).Range("1:4").EntireRow.Delete
oBook.SaveAs csv, 6
oBook.Close False
oExcel.Quit
WScript.Echo "Done"
Thanks to Ansgar Wiechers I was able to come up with this script
xls = "C:\[Path]"
csv = "c:\[Destination]"
Set oExcel = CreateObject("Excel.Application")
Set oBook = oExcel.Workbooks.Open(xls)
oBook.Worksheets(2).Activate
oBook.Worksheets(2).Rows("1:4").Delete
oBook.SaveAs csv, 6
oBook.Close False
oExcel.Quit
And it runs like a champ in cmd. Thanks a million!
However, I went to implement this into my process and found out that SQL Server Agent has major issues in executing VBScripts.
cscript is the command that is suggested to execute the script, but it doesn't work. After more research I found that other people have had similar issues and they all suggest writing the script in VB.NET instead of VBScript. This way SSIS can process the script.
Ansgar I marked your response as the answer since it answered my question, but sadly it only lead me to a dead end with VBScript.
I want to create a vbscript program that reads a .ini file to get parameters and use it.
My parameter file contains several parameters:
propertyfile.ini
"C:\PROGRA~1\narrowcast\scripts\transferStatusLog.txt"
..other parameters
..more parameters
my vbscript will read the file and use it
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objPropertyFile = objFSO.OpenTextFile("C:\PROGRA~1\scripts\propertyfile.ini", 1)
Do Until objPropertyFile.AtEndOfStream
myfile = objPropertyFile.ReadLine
... other parameters for use on other fso object
Loop
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objLogProgram = objFSO.CreateTextFile(myfile)
Im having an error bad file name or number. Please help
You are reading in the quotes - vbscript is not liking that. You'll need to strip them off.
Here's a quick and dirty replacement. Don't forget to add a check to see if it exists - otherwise if it doesn't you'll probably get a path not found error.
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objPropertyFile = objFSO.OpenTextFile("C:\PROGRA~1\scripts\propertyfile.ini", 1)
Do Until objPropertyFile.AtEndOfStream
myfile = replace (objPropertyFile.ReadLine,"""","")
Loop
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objLogProgram = objFSO.CreateTextFile(myfile)
What are we doing here?
We are simply telling vbscript to replace the double quote character with nothing (we had to "escape it, by double quoting, etc):
myfile = replace (objPropertyFile.ReadLine,"""","")
I hope this helps.
I have requirement that I'm not really sure on how to go about it. I have a file Doc.xml, this is in Microsoft XML format. I need to create a VB script that will change/convert the Doc.xml to Doc.xlsx, so when the user tries to open the file it will open as an Excel file.
One of the requirements is that this script will be run from the Windows Scheduler.
Any ideas or recommendation will be really appreciated.
This is the script I created and is working, but when I try to change the SaveAs extension to ".csv" the file is not being saved correctly. I guess I need to find out what the code is for saving in CSV.
Dim objXLApp, objXLWb, objXLWs
Set objXLApp = CreateObject("Excel.Application")
objXLApp.Visible = True
Set objXLWb = objXLApp.Workbooks.Open("C:\Users\jmejia\Desktop\XML_F\ZOOSHR_130622.xml")
'Do nothing with File, just open it to be save agains as a new file format
objXLWb.SaveAs "C:\Users\jmejia\Desktop\XML_F\ZOOSHR_130622.xlsx", 51
objXLWb.Close (False)
Set objXLWs = Nothing
Set objXLWb = Nothing
objXLApp.Quit
Set objXLApp = Nothing
If your file was created and exported from Excel > 2006? then it will have the tags in it such that double clicking in explorer on a windows machine with any Excel that supports xml format will automatically open it in Excel.
Your file is likely to start with something like:
<?xml version="1.0"?>
<?mso-application progid="Excel.Sheet"?>
<Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet"
xmlns:o="urn:schemas-microsoft-com:office:office"
xmlns:x="urn:schemas-microsoft-com:office:excel"
xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet"
xmlns:html="http://www.w3.org/TR/REC-html40">
<DocumentProperties xmlns="urn:schemas-microsoft-com:office:office">
Const xlXLSX = 51
REM 51 = xlOpenXMLWorkbook (without macro's in 2007-2013, xlsx)
REM 52 = xlOpenXMLWorkbookMacroEnabled (with or without macro's in 2007-2013, xlsm)
REM 50 = xlExcel12 (Excel Binary Workbook in 2007-2013 with or without macro's, xlsb)
REM 56 = xlExcel8 (97-2003 format in Excel 2007-2013, xls)
dim args
dim file
dim sFile
set args=wscript.arguments
dim wshell
Set wshell = CreateObject("WScript.Shell")
Set objExcel = CreateObject("Excel.Application")
Set objWorkbook = objExcel.Workbooks.Open( wshell.CurrentDirectory&"\"&args(0))
objExcel.DisplayAlerts = FALSE
objExcel.Visible = FALSE
objWorkbook.SaveAs wshell.CurrentDirectory&"\"&args(1), xlXLSX
objExcel.Quit
Wscript.Quit