VBS OpenTextFile returns unexpected result - text

This is my code:
Set fso = CreateObject("Scripting.FileSystemObject")
strText = fso.OpenTextFile(strLocalFolderName & "\" & Oudste).ReadAll()
msgbox strText
But strText contains rubbish after these lines.
How can that be?

Darn! The boolean option within OpenTextFile examples is often left out!
fso.OpenTextFile(Path, ForReading, False, TriStateTrue)
Path is the path to the file. ForReading should be 1 for read only.
Then this False is the often omitted boolean (false means it's not written )
Only when the boolean is added correctly, you can pick a type of txt file.
In my case unicode so I pick -1 for the Tristate.
Tip: if you ever get weird results with textfiles, open in notepad, choose save as and then it will reveal what kind of text you actually have.

Your problem can be because a lot of thigs like the encode of target file, one of the most common encode us UTF-8 you can chage it with notepad++:
How do I convert an ANSI encoded file to UTF-8 with Notepad++?
I think you should put some validation code to find the real problem, I suggest this code:
ForReading=1 'Open a file for reading only. You can't write to this file.
ForWriting=2 'Open a file for writing.
ForAppending=8 'Open a file and write to the end of the file.
CreateIfNotExist=TRUE 'If you use FALSE you get error if not exist
set fso = CreateObject("Scripting.FileSystemObject")
if (fso.fileexists(".\test.txt")) then
set ts = fso.OpenTextFile(".\test.txt", ForReading, CreateIfNotExist)
if NOT ts.AtEndOfStream then
s = ts.ReadAll
msgbox s
else
msgbox "End of file"
end if
else
msgbox "File not found"
end if

Related

Modify and replace an XML file through a Macro to the same path (Excel VBA)

I have a custom-button in my excel sheet, and when the user clicks it, the code enables the user to upload a file, and then code modifies the uploaded file, and stores the modified contents in a String variable s. -
Option Explicit
Sub Button1_Click()
Dim fso As Object, ts As Object, doc As Object
Dim data As Object, filename As String
Dim ws As Worksheet
Set ws = ActiveSheet
' select file
With Application.FileDialog(msoFileDialogFilePicker)
If .Show <> -1 Then Exit Sub
filename = .SelectedItems(1)
End With
' read file and add top level
Set doc = CreateObject("MSXML2.DOMDocument.6.0")
Set fso = CreateObject("Scripting.FileSystemObject")
Set ts = fso.OpentextFile(filename)
doc.LoadXML Replace(ts.readall, "<metadata>", "<root><metadata>", 1, 1) & "</root>"
ts.Close
' import data tag only
Dim s As String
Set data = doc.getElementsByTagName("data")(0)
s = data.XML
' MsgBox s
' replace the original XML file with contents of variable s here
If MsgBox(s & vbCrLf, vbYesNo) = vbYes Then
Application.SendKeys ("%lt")
Else
MsgBox "Ok"
End If
End Sub
Let's say I clicked the button and uploaded an XML file C:/My Folder/sample.xml. Now the code modifies it, and updates the file (with the new contents stored in variable s). Here's a representative image - (the modified contents is direct value of s variable)
How do I achieve the above? Kindly guide... Thanks!
See CreateTextFile method of a TextStream Objects
Set ts = fso.CreateTextFile(filename, True)
ts.Write s
ts.Close
Why not continue with XML methods by loading the wanted string again (after Set data = doc.getElementsByTagName("data")(0)):
doc.LoadXML data.XML
doc.Save filename
Side note to posted code
It's worth mentioning that the somehow peculiar insertion of a starting <root> and closing </root> tag into the loading xml string via
doc.LoadXML Replace(ts.readall, "<metadata>", "<root><metadata>", 1, 1) & "</root>"
is a only a workaround rebuilding a well-formed xml input thus avoiding
Error `-1072896683 XML document must have a top level element.`
So imo you might consider changing your pattern files to include metadata not at top-level, but at a subsequent hierarchy level already in design to provide for a loadable, well-formed xml markup.

VBA reading non-english characters causes errors

I am using a macro that reads every excel file in one folder and subfolders and refreshes it by opening the file and closing it with 'save changes' attribute as True. The problem is that VBA doesn't read non-english letters correctly and it causes error when trying to save the spreadsheet. My region settings in Windows control panel are correct. When I try to use the beta option of using Unicode UTF-8 for every language it works but that causes a lot of other programs I use to display some weird characters. The language I try to incorporate is polish. Any idea what to do?
Sub RefreshExcelDocs()
Const startFolder As String = "C:\Users\Patryk\Downloads\Przykład óżęą\Folder\"
Dim file As Variant, wb As Excel.Workbook
For Each file In Filter(Split(CreateObject("WScript.Shell").Exec("CMD /C DIR """ & startFolder & "*.xl*"" /S /B /A:-D").StdOut.ReadAll, vbCrLf), ".")
Set wb = Workbooks.Open(file)
wb.Close SaveChanges:=True '
Set wb = Nothing
Next
End Sub

Why after running Windows updates do I get "Run-Time Error 62 Input Past End of File"?

Any idea why I keep getting a Run -time error 62 Input past end of file error with the following code when using the Input function. The help function tells me the file is in binary and I should use either LOF or Seek however neither seems to work. This code worked fine until a recent Windows and Microsoft update to my computer.
Dim fldr As FileDialog
Dim sItem As String
Set fldr = Application.FileDialog(msoFileDialogFilePicker)
With fldr
.Filters.Clear
.Filters.Add "All files", "*.*"
.Title = "Select a CFG File to Convert fromatting from R2013 to 1991."
.AllowMultiSelect = False
.InitialFileName = ActiveWorkbook.Path 'Application.DefaultFilePath
If .Show <> -1 Then Exit Sub
sItem = .SelectedItems(1)
End With
set fldr = Nothing
Open sItem For Input As #1
dataArray = Split(Input(LOF(1), #1), vbLf)
Close #1
If Len(dataArray(2)) - Len(Replace(dataArray(2), ",", "")) = 9 Then
MsgBox "It appears the comtrade file format already conforms to the 1991 standard version." & vbNewLine & "" & vbNewLine & "Conversion was Aborted."
Exit Sub
End If
I'm trying to count the number of commas in line 3 of the selected file.
dataArray = Split(Input(LOF(1), #1), vbLf)
That's a lot of work for a single line of code.
You're not validating the entire file, only the second line. You're also hard-coding a file handle#, and that can cause other problems - use the FreeFile function to get a free file handle from VBA instead of assuming #1 is available. Or better, use the higher-abstraction FileSystemObject instead (reference the Microsoft Scripting Runtime library):
With New Scripting.FileSystemObject
With .OpenTextFile(filename, ForReading)
Dim contents As String
contents = .ReadAll
End With
End With
Dim lines As Variant
lines = Split(contents, vbNewLine)
Or, without referencing the Scripting library:
Const ForReading As Long = 1
With CreateObject("Scripting.FileSystemObject")
With .OpenTextFile(filename, ForReading)
Dim contents As String
contents = .ReadAll
End With
End With
Dim lines As Variant
lines = Split(contents, vbNewLine)
Note that when you code against Object, member calls are late-bound: you don't get IntelliSense/autocompletion, and you don't get any compile-time validation; typos will merrily compile (and blow up at run-time with error 438). Prefer early-bound code everywhere - I can't think of a reason to use late binding against the Scripting library though, since that library is the exact same on every Windows machine built this century.

Read a text file for a specific string and open msgbox if not found

How do I open a text file and look for a specific string?
I want that the string "productactivated=true" determines whether to display a message on the Userform telling the user to activate.
A few days ago I asked for help with opening a text file and doing some reading and writing, so I came up with this
Open "application.txt" For Output As #1
ClngLine = lngLine + 1
Line Input #f, strLine
If InStr(1, strLine, strSearch, vbBinaryCompare) > 0 Then
MsgBox "Search string found in line " & lngLine, vbInformation
blnFound = True
Close #1
For your solution two files will be used showing how to read and write to text files. The writing was added just to show you how to do it but does not seem to be needed for your solution per your question statement. For this solution purpose, all the files are in the same folder.
The first file is the file being read from. For the demo purpose, since not data was supplied it was created with the following data and named "TextFile.txt":
This is the first line.
This is the second line and has productactivated=true.
Third line lays here.
productactivated=true is found in line four.
The second file is the file being written to. For the demo purpose just to show how it is done, but per your question isn't needed, and named "TextFile.txt":
This is the first line.
This is the second line and has productactivated=true.
Third line lays here.
productactivated=true is found in line four.
The VBA code:
Sub search_file()
Const ForReading = 1, ForWriting = 2
Dim FSO, FileIn, FileOut, strSearch, strTmp
'FileSystemObject also called as FSO, provides an easy object based model to access computer’s file system.
Set FSO = CreateObject("Scripting.FileSystemObject")
'Set FileIn to the file for reading the text into the program.
Set FileIn = FSO.OpenTextFile("TextFile.txt", ForReading)
'Set FileOut to the file for writing the text out from the program.
'This was added just to show "how to" write to a file.
Set FileOut = FSO.OpenTextFile("TextFileRecordsFound.txt", ForWriting, True)
'Set the variable to the string of text you are looking for in the file you are reading into the program.
strSearch = "productactivated=true"
'Do this code until you reach the end of the file.
Do Until FileIn.AtEndOfStream
'Store the current line of text to search to work with into the variable.
strTmp = FileIn.ReadLine
'Determines whether to display a message
'(Find out if the search text is in the line of text read in from the file.)
If InStr(1, strTmp, strSearch, vbTextCompare) > 0 Then
'Display a message telling the user to activate.
MsgBox strSearch & " was found in the line:" & vbNewLine & vbNewLine & strTmp, , "Activate"
'Write the line of text to an external file, just to demo how to.
FileOut.WriteLine strTmp
End If
Loop 'Repeat code inside Do Loop.
'Close files.
FileIn.Close
FileOut.Close
End Sub

Excel, VBA, Macro, File - Open or Create, Dialog

I am writing a macro in MS excel using VBA. I need to open or create a file to write to.
Potentially the file may have a different extension (i.e. .cal) but internally it just contains text.
I have looked over a lot of examples that create a file by explicitly stating the path for the new file (here's one I found):
strFileName = "C:\test.txt"
Open strFileName For Output As #iFileNumber
Other examples open a file which already exists.
I would like to have a popup/dialog which allows the user to "either" open an existing file "or" create a new one. I assume this is possible.
I have played around with the Application.FileDialog(....) function using strings/paths and objects without much success so far.
With Application.FileDialog(...) your user should be able to create a new text file as they would in Windows Explorer (by right-clicking and selecting New->Text File), they can then select that file to output data to.
The below SelectFile(...) function returns the path to a selected file (or an empty string if no file was selected). Using this function as-is it is only possible for the user to select one file, but given the context I would hope this isn't a problem.
Public Sub SelectOrCreateFile()
Dim strFileName As String
Dim iFileNum As Integer
iFileNum = FreeFile
strFileName = SelectFile
If strFileName <> "" Then
Open strFileName For Output As #iFileNum
'### WRITE YOUR DATA ###
Close #iFileNum
End If
End Sub
'Returns File Path of file selected with file selection dialog
Public Function SelectFile(Optional DefaultPath As String = "", _
Optional FileType As String = "All Files", _
Optional FileExtension As String = "*.*") As String
Dim F As Object
Set F = Application.FileDialog(msoFileDialogFilePicker)
'Set up FileDialog properties
F.Filters.Clear
F.Filters.Add FileType, FileExtension
F.AllowMultiSelect = False
F.Title = "Select File"
F.ButtonName = "Select"
If DefaultPath <> "" Then F.InitialFileName = DefaultPath
'FileDialog.Show returns False if the user cancels
If F.show Then
SelectFile = F.SelectedItems(1)
Else
MsgBox "No File Selected", vbInformation, "Cancelled"
SelectFile = ""
End If
Set F = Nothing
End Function
Hope this helps!

Resources