Encoding issue when creating MS Word file using VBScript - vbscript

I'm trying to write a script in VBScript which should open Microsoft Word and write down some text.
The script works as expected as long as the text I'm writing is in English.
However, when the text is in Hebrew or in Chinese I only get Gibberish in MS Word.
I tried to save the script file as UTF-8, but I can no longer run it after this change.
I also tried to wrap it so it will be a wsf script and it didn't worked either.
Couldn't find any other suggestion on Google.
Here is the script (This time I'm trying to write the word "שלום" in Hebrew).
Set objWord = CreateObject("Word.Application")
objWord.Visible = True
Set fso = CreateObject("Scripting.FileSystemObject")
Set objDoc = objWord.Documents.Add()
Set objSelection = objWord.Selection
objSelection.TypeText "שלום"
When I run this script, it opens MS word and write down "ùìåí" instead of "שלום".

You can save a script file with the following encoding:
ANSI. Only 256 chars can be used: 0..127 is standard ASCII, and upper part depends on locale you have chosen in system settings, or overridden by SetLocale().
Unicode (UCS-2 or UTF-16, Little Endian). It works if saved with BOM, or without BOM. There is 1 112 064 available chars. In my opinion it is the easiest way for you to get your script to work. But file size increased by 2 times.
UTF-8. Encodes any symbol in Unicode code space. Script can be ran only if saved without BOM.
UTF-8 as .wsf file with first tag <?XML version="1.0" encoding="UTF-8"?>
ANSI, but put all strings like WScript.Echo ChrW(1513) & ChrW(1500) & ChrW(1493) & ChrW(1501).
Notepad++ and Notepad2 are handy to clearly set the necessary encoding.
Regarding item 3. Generally, Windows Script Host is unable to run script file in UTF-8 encoding with BOM, and recognizes each byte of UTF-8-encoded file without BOM as ANSI-encoded char, while downloading the file into memory. I can suggest a work-around that allows to rectify incorrectly recognized chars being contained in variables, but you know, Unicode is a better way. Here is example:
s = "שלום"
WScript.Echo s ' wrong encoding
r = FixChars(s)
WScript.Echo r ' שלום
Function FixChars(s)
Dim r, p
r = ""
For p = 1 To Len(s)
r = r & ChrB(Asc(Mid(s, p, 1)))
Next
With CreateObject("ADODB.Stream")
.Type = 2
.Mode = 3
.Charset = "Unicode" ' HKLM\SOFTWARE\Classes\MIME\Database\Charset
.Open
.WriteText r
.Position = 0
.Charset = "UTF-8"
r = .ReadText
.Close
End With
Do While LeftB(r, 2) = ChrB(&HFD) & ChrB(&HFF)
r = MidB(r, 3)
Loop
FixChars = r
End Function
You shouldn't change locale via SetLocale() from script start till FixChars() completion, otherwise it will give an error.And the following code is an example for item 4:
<?XML version="1.0" encoding="UTF-8"?>
<job>
<script language="VBScript">
<![CDATA[
WScript.Echo "שלום"
]]>
</script>
</job>

Related

How to set Japanese characters(UTF-8) in VBScript variables

I have a script where I need to set some Japanese text to a variable. But since vbscript is not supporting japanese texts, it get converted to some garbled text like トコジャパンã‹ã‚‰ã®æ–°è¦æ³¨æ–‡. My actual japanese text is トコジャパンからの新規注文.
My script will look like below
dim emlObj
set emlObj = CreateObject("EMailObject")
emlObj.Subject = "Train - New Orders From Costco Japan | コストコジャパンからの新規注文"
emlObj.Body = "Some japanese body text"
emlObj.Send()
I do not have any other options like storing this text in file or db and process in some other scripts as of now. since this script will be used by our customers and they will set their expected email body text. We'll use them for sending it as a mail.
I've also tried ADODB.Steam but that works only when reading the text from file.
Can someone please suggest a way to set the japanese text in vbscript?.
Edit:
To put a clarity on what i really needed.
I want to hard-code a japanese text to a variable in VBScripts.
You can use this solution:
Dim objStream, body, subject
Set objStream = CreateObject("ADODB.Stream")
objStream.CharSet = "utf-8"
objStream.Open
objStream.WriteText "Subject in Japanese"
objStream.SaveToFile "C:\Subject.txt", 2
objStream.Close
objStream.Open
objStream.WriteText "Body in Japanese"
objStream.SaveToFile "C:\body.txt", 2
objStream.Close
objStream.CharSet = "utf-8"
objStream.Open
objStream.LoadFromFile "C:\Body.txt"
body = objStream.ReadText()
objStream.Close
objStream.CharSet = "utf-8"
objStream.Open
objStream.LoadFromFile "C:\Subject.txt"
subject = objStream.ReadText()
objStream.Close
' Now body is stored in body variable and subject is in subject now do anything with them
IMPORTANT: Since you are not using ADODB.Stream to load your content, then be sure to save your actual VBScript file as UTF-16 LE encoding. Your script may optionally benefit from a Unicode byte-order-mark (BOM) header, as well -- depending upon how the VBScript engine and EmailObject respond.
Once the VBScript file is in the proper encoding, this script works fine for me:
With CreateObject("CDO.Message")
With .Configuration.Fields
.Item("http://schemas.microsoft.com/cdo/configuration/sendusing") = 2
.Item("http://schemas.microsoft.com/cdo/configuration/smtpserver") = "smtp.somemailserver.net"
.Item("http://schemas.microsoft.com/cdo/configuration/smtpconnectiontimeout") = 10
.Item("http://schemas.microsoft.com/cdo/configuration/smtpserverport") = 25
.Update
End With
.BodyPart.Charset = "utf-8"
.BodyPart.ContentTransferEncoding = "base64"
.TextBody = "コストコジャパンからの新規注文"
.TextBodyPart.Charset = "utf-8"
.HTMLBody = "<p>コストコジャパンからの新規注文</p>"
.HTMLBodyPart.Charset = "utf-8"
.From = "me#somemailserver.net"
.To = "you#somemailserver.net"
.Subject = "Train - New Orders From Costco Japan | コストコジャパンからの新規注文"
.Send()
End With
Note: I am using CDO.Message above, not EmailObject.
Hope this helps.

WMI Query Output to variable [duplicate]

I can't get the following function in VBScript to work. I am trying to get all of the files in a folder and loop through them to get the highest numbered file. (file name format is log_XXX.txt) The problem that I am having is that the code never enters my For Each loop. I am new to VBScript, but I don't seem to understand why this won't work.
Function GetFileNumber(folderspec)
Dim fso, f, f1, fc, s, tempHighNum
Set fso = CreateObject("Scripting.FileSystemObject")
Set f = fso.GetFolder(folderspec)
WScript.Echo f.Files.Count : rem prints 3
Set fc = f.Files
WScript.Echo fc.Count : rem prints 3
Set tempHighNum = "000"
For Each f1 in fc
WScript.Echo f1.Size : rem does not print
WScript.Echo f1.Type : rem does not print
WScript.Echo f1.Name : rem does not print
s = Right(f1.name,3)
IF NOT(ISNULL(s)) THEN
IF (s > tempHighNum) THEN
tempHighNum = s
END IF
END IF
Next
GetFileNumber = tempHighNum
End Function
Change this line:
Set tempHighNum = "000"
to the following:
tempHighNum = "000"
You are attempting to set the tempHighNum variable to a string type. Therefore, you should not use the Set keyword. Set is only needed when assigning object types to variables.
I am not sure how your script works so I put this HTML application together for you. It uses a batch file called Dir.Bat located in C:\Batch which makes a file called Data.Txt located in c:\Temp. Then the script takes
over. The script reads the file Data.Txt line by line. As each line is read two split statements are used to separate out the string in the text file's name. After that I collect those strings containing numbers into the variable ListCol as I test for larger and larger numbers. I finally wind up with the largest number which I place in your original variable tempHighNum. I will post the HTA file and the Dir.Bat file. I know I did not write the script as a function using a parameter so if you really need to use a parameter, I will try to help you by changing the HTA file to make it possible to enter the path and file name in a TextBox. That should make it easy to
change and use. I added and changed a thing or two to make it run smoother.
I am not sure how your script works so I put this HTML application together for you. It uses a batch file called Dir.Bat located in C:\Batch which makes a file called Data.Txt located in c:\Temp. Then the script takes
over. The script reads the file Data.Txt line by line. As each line is read two split statements are used to separate out the string in the text file's name. After that I collect those strings containing numbers into the variable ListCol as I test for larger and larger numbers. I finally wind up with the largest number which I place in your original variable tempHighNum. I will post the HTA file and the Dir.Bat file. I know I did not write the script as a function using a parameter so if you really need to use a parameter, I will try to help you by changing the HTA file to make it possible to enter the path and file name in a TextBox. That should make it easy to
change and use. I added and changed a thing or two to make it run smoother.
<HTML><!-- C:\HTML_and_HTA_CODE_EXAMPLES\ATest.Hta -->
<HEAD>
<TITLE>ATest.Hta</TITLE>
<HTA:APPLICATION ID="HTA MyApp"
APPLICATIONNAME="Help4Saul Dolgin"
BORDER ="thick"
BORDERSTYLE ="complex"
CAPTION ="yes"
CONTEXTMENU ="no"
ICON ="http://Your URL/your icon.ico"
INNERBORDER ="yes"
MAXIMIZEBUTTON ="yes"
MINIMIZEBUTTON ="yes"
NAVIGABLE ="no"
SCROLL ="no"
SHOWINTASKBAR ="yes"
SINGLEINSTANCE ="yes"
SYSMENU ="yes"
VERSION ="1.0"
WINDOWSTATE ="Normal"/>
</HEAD>
<style>
.ExBt21 {background:"#E0E0E0";Color:"red";}/* For Exit Button */
.Spn4 {font-family:"arial";font-weight:"bold";Color:"blue"}
.Spn2 {Color:"red"}
.tAr1 {font-family:"arial";font-weight:"bold";Color:"blue"}
</style>
<SCRIPT Language="VBScript">
Sub GetFileNumber
Dim FSO, f, fc, tempHighNum, strLine, objSHO, line
Dim DataArr, Data1Arr, Data2Arr, ListCol
fc=""
ListCol=""
tempHighNum=000
Set objSHO=CreateObject("WScript.Shell")
objSHO.run "C:\Batch\Dir.bat"
Set FSO = CreateObject( "Scripting.FileSystemObject" )
Set f = FSO.OpenTextFile("c:\Temp\Data.Txt", "1")
Do Until f.AtEndOfStream
fc = fc & f.ReadLine & vbLf
Loop
tArea1.innerHTML=fc
Data1Arr = Split(fc,vbLf)
Count=UBound(Data1Arr)
For x=0 To Count
DataArr = Split(Data1Arr(x),".")
If x <= Count-1 Then
Data2Arr = Split(DataArr(0),"_")
ListCol = ListCol & Data2Arr(1) & vbLf
If Data2Arr(1) > tempHighNum Then
tempHighNum = Data2Arr(1)
End If
End If
Next
Span2.innerHTML=tempHighNum
End Sub
Sub ExtBtn:Window.close:End Sub' Exit Script For Window
</SCRIPT>
<BODY bgcolor="#D0D0D0">
<button OnClick="GetFileNumber">Button To Press</button><br/>
<span id="Span1" class="Spn1">The biggest No. is: </span><span id="Span2" class="Spn2"></span><br/><br/>
<span Id="Span3" Class="Spn3">Dir.Bat looks in: </span><span Id="Span4" Class="Spn4">C:\Temp\Log_???.Txt</span><br/>
<textarea Id="tArea1" class="tAr1" rows="10"></textarea><br/><br/>
<input id="ExBtn21" class="ExBt21" type="Button" name="ExitBtn21" OnClick="ExtBtn" value="&nbsp-Exit-&nbsp"/><!-- Exit Button -->
</BODY>
</HTML>
The Dir.Bat file is next:
#Echo Off
Dir/B c:\Temp\Log_???.Txt>c:\Temp\Data.Txt

vbscript compare string contents (folder directory) of text files and creates the missing folders

I am currently working on a school assignment to compare strings within text files. These text files contains paths of folder directories. If a directory is not found on the other textfile, it will create that directory, else nothing will happen.
diretory1.txt contains directory strings that are:
C:\mcgfiles\avp
C:\mcgfiles\temp
C:\mcgfiles\logs\activity
C:\mcgfiles\logs\program
C:\mcgfiles\logs\status
C:\mcgfiles\generatedhtml
and diretory2.txt, contains the following
C:\mcgfiles
C:\mcgfiles\avp
C:\mcgfiles\temp
C:\mcgfiles\logs
C:\mcgfiles\logs\activity
C:\mcgfiles\logs\program
C:\mcgfiles\logs\status
C:\mcgfiles\generatedhtml
In the case of my textfiles, directories "C:\mcgfiles" and "C:\mcgfiles\logs" will be created on my drive C:\ since they are missing.
Here is the code I used:
Set objFSO = CreateObject("Scripting.FileSystemObject")
Const ForReading = 1
Set objFile1 = objFSO.OpenTextFile("C:\scripts\directory1.txt", ForReading)
strAddresses = objFile1.ReadAll
objFile1.Close
Set objFile2 = objFSO.OpenTextFile("C:\scripts\directory2.txt", ForReading)
Do Until objFile2.AtEndOfStream
strCurrent = objFile2.ReadLine
If InStr(strAddresses, strCurrent) = 0 Then
objFSO.CreateFolder(strCurrent)
End If
Loop
It works fine when I use "C:\mcgfiles\temp" as the missing directory. But it cant differentiate what's missing when I use "C:\mcgfiles" or "C:\mcgfiles\logs". Maybe its because I used InStr function and it considers "C:\mcgfiles" and "C:\mcgfiles\logs" not missing since it can also be found in "C:\mcgfiles\logs\activity" etc.
I tried to use strComp but still nothing happens. Please help. Thank you
InStr() "returns the position of the first occurrence of one string within another". So "C:\mcgfiles" is found in "C:\mcgfiles\logs". If all of the pathes in the string you search in are terminated by an EOL marker (eg.g vbCrLf) you can use target & EOL as the needle:
>> haystack = "c:\a\b;c:\a;"
>> eol = ";"
>> needle = "c:\a" & eol
>> WScript.Echo InStr(haystack, needle)
>>
8
Other techniques - e.g. using a dictionary of the pathes - are possible, but would need more work.

VBS Readline - using instr(), to match data whilst ignoring extra spaces

I'm trying to find a way to enhance the reliability of my script. It already works but can be thrown off with a simple extra space in the imported text file.
So I'd like to change my script to Readline if I can find a way to do something like:
Example of text in the .txt file:
FLIGHTS OVER TUSKY PLEASE FILE:
AT OR WEST OF A LINE RBV..LLUND..BAYYS..PUT..DIRECT
FLIGHTS OVER EBONY PLEASE FILE:
AT OR WEST OF A LINE RBV..LLUND..BAYYS..PUT..DIRECT
I know the following doesn't work but if there was a simple modification this would be good.
set WshShell = WScript.CreateObject("WScript.Shell")
Return = WshShell.Run("C:\Downloads\software\putty.exe -load "testing")
set objFSO = CreateObject("Scripting.FileSystemObject")
set objFile = objFSO.OpenTextFile("C:\Users\AW\Desktop\Entries1.txt")
strLine = objFile.ReadAll
If InStr(strLine1, "OVER TUSKY PLEASE") and InStr(strLine2, "BAYYS..PUT..DIRECT") Then
trans307="TUSKY"
ind306="4"
WHAT I'M USING NOW:
I edit the text file in notepad++ to FIND & REPLACE "\n" with "" and "\r" with " " and then it's all one text string and I search for strings within that string.
If InStr(strLine, "FLIGHTS OVER TUSKY PLEASE FILE: AT OR WEST OF A LINE ..RBV..LLUND..BAYYS..PUT..DIRECT") _
or InStr(strLine, "FLIGHTS OVER TUSKY PLEASE FILE: AT OR WEST OF A LINE RBV..LLUND..BAYYS..PUT...DIRECT") Then
trans308C="TUSKY"
ind308C="4"
Problem: If the creators of the text file put another space " " anywhere in this line "AT OR WEST OF A LINE RBV..LLUND..BAYYS..PUT..DIRECT" the script will not identify the string. In the above example I have had to create another or InStr(strLine, "") statement with an extra space or with a couple of dots.
UPDATE:
I will try something like:
set objFSO = CreateObject("Scripting.FileSystemObject")
set objFile = objFSO.OpenTextFile("C:\Users\AW\Desktop\Entries1.txt")
strLine1 = objFile.Readline(1)
strLine2 = objFile.Readline(2)
If InStr(strLine1, "FLIGHTS OVER TUSKY") and InStr(strLine2, "RBV..LLUND..BAYYS..PUT..DIRECT") Then
trans1="TUSKY"
ind1="4"
and see if I can get that to read 2 lines at a time, and loop through the text file.
If you're scared of regex and looking for an alternative, you could create a clunky function to add to your script. Based on your samples, it would seem that fullstops are also never normally used for normal purposes and tend to represent spaces. (I would recommend using Regex instead!)
Using these presumptions, you could create a clunky function like this, that looks for fullstops, and converts them to spaces, removing extra spaces.. Obviously, this relies heavily on your input source files not changing too much - you really should be using a regex to work this stuff out properly.
You could test for the basic expected results using something like the function below.
For example say you had a line of text set in firLine with multiple spaces or fullstops, the function would recognize this:
firLine = "THIS.IS.A.TEST..YOU...SEE MULTIPLE SPACES"
if instr(sanitize(firLine),"THIS IS A TEST YOU SEE MULTIPLE SPACES") then
wscript.echo "Found it"
End If
Here's the clunky function that you could just paste at the end of your script:
Function sanitize(srStr)
Dim preSanitize, srC, spaceMarker
preSanitize = ""
for srC = 1 to len(srStr)
if mid(srStr, srC, 1) = "." then
preSanitize = preSanitize & " "
else
preSanitize = preSanitize & mid(srStr, srC, 1)
End If
spaceMarker = false
sanitize = ""
for srC = 1 to len(preSanitize)
If mid(preSanitize, srC, 1) = " " then
if spaceMarker = false then
sanitize = sanitize & mid(preSanitize, srC, 1)
spaceMarker = true
End If
else
sanitize = sanitize & mid(preSanitize, srC, 1)
spaceMarker = false
End If
Next
End Function
InStr() is a good tool for checking whether a strings contains a fixed/literal string or not. To allow for variation, you should use Regular Expressions (see this or that).
First of all, however, you should work on your specs. Describe in plain words and with some samples what you consider (not) to be a match.
E.g.: A string containing the words "FLIGHTS", "OVER", and "TUSKY" in that order with at least one space in between is a match - "FLIGHTS OVER TUSKY", "FLIGHTS OVER TUSKY"; "FLIGHTS OVER TUSKANY" is a 'near miss' - what about "AIRFLIGHTS OVER TUSKY"?
GREAT NEWS! I finally figured out how to do this.
Here is a snippet from "Entries1.txt"
FLIGHTS OVER BRADD KANNI PLEASE FILE:
VIA J174.RIFLE..ACK..DIRECT
OR RBV.J62.ACK..DIRECT
FLIGHTS OVER KANNI WHALE PLEASE FILE:
VIA J174.RIFLE..ACK..DIRECT OR
FLIGHTS OVER WHALE PLEASE FILE:"
ETC, ETC
set WshShell = WScript.CreateObject("WScript.Shell")
set objFSO = CreateObject("Scripting.FileSystemObject")
set objFile = objFSO.OpenTextFile("C:\Users\AW\Desktop\Entries1.txt")
Do until objFile.AtEndOfStream
firLine = objFile.ReadLine
If InStr(firLine, "FLIGHTS OVER KANNI WHALE PLEASE") Then
secLine = objFile.ReadLine
If InStr(secLine, "J174.RIFLE..ACK..DIRECT") Then
'I'm going to change the below once I piece it all together.
WScript.Echo "works"
Else WScript.Echo "Not found"
'cut, paste and modify all my "IF" statements below
End If
End If
loop

how to make ascii file for accounting software with vbscript and ASP

i need to have an ascii file that have several lines in it for accounting.
in everyline i will have the text and numbers for example numbers and spaces with specific length for every column of data
first column is 3 char length
second is 5
third is 10 and etc...
then i need the end of the line to end with CR + LF
how do i do an ascii file from classic asp and vbscript?
You use FSO (FileSystemObject) to work with files in VBScript. This MSDN Page, Working with Files, shows you how to create and write to files.
Here's a page that has a sample that uses VBScript in an ASP page to create a text file.
My guess, you need to manage a text file like a database. If I'm right, you can do it using Text File Driver.
You need a schema.ini file for the data construct configuration and an existing text file (myfile.csv).
schema.ini
[myfile.csv]
Format=FixedLength
CharacterSet=ANSI
ColNameHeader=False
Col1=first Text Width 3
Col2=second Text Width 5
Col3=third Text Width 10
;[myotherfile.csv]
;Format=FixedLength
;CharacterSet=ANSI
; etc.
myfile.csv (maybe not certain but there are three columns per line with the above configuration.)
abcdefghijklmnopqrstu
123123451234567890
Things to do side of ASP are like classical database operations also.
Const adLockReadOnly = 1
Dim adoCon, adoRS
Set adoCon = Server.CreateObject("Adodb.Connection")
adoCon.Open "Provider=Microsoft.Jet.OLEDB.4.0;Data Source="& Server.Mappath(".") & _
";Extended Properties=""text"""
Set adoRS = Server.CreateObject("Adodb.Recordset")
With adoRS
.Open "Select * From [myfile.csv]", adoCon, , adLockReadOnly
While Not .Eof
Response.Write( _
.Fields("first").Value & " - "& _
.Fields("second").Value & " - "& _
.Fields("third").Value & _
"<br />")
.MoveNext
Wend
.Close
End With
Set adoRS = Nothing
'Data insert : new line ends with CR + LF automatically.
adoCon.Execute "Insert Into [myfile.csv] Values('aaa','bbbbb','cccccccccc')"
adoCon.Close
Set adoCon = Nothing

Resources