Sendkeys Only Writing First Character from Text File - vba

I'm trying to write everything from a text file, but it's only writing the first character.
Here's my code:
Sub Main
Dim TextFile As Integer
Dim FilePath As String
Dim FileContent As String
'File Path of Text File
FilePath = "C:\Users\Username\Desktop\Clipboard.txt"
'Determine the next file number available for use by the FileOpen function
TextFile = FreeFile
'Open the text file
Open FilePath For Input As TextFile
'Store file content inside a variable
FileContent = Input(LOF(TextFile), TextFile)
'Report Out Text File Contents
SendKeys FileContent
'Close Text File
Close TextFile
End Sub
I've also tried this, but similarly only write the first character:
Sub Main
Dim objFSO
Set objFSO = CreateObject("Scripting.FileSystemObject")
Dim objTextStream
Const strFileName = "C:\Users\Username\Desktop\Clipboard.txt"
Const fsoForReading = 1
If objFSO.FileExists("C:\Users\Username\Desktop\Clipboard.txt") Then
'The file exists, so open it and output its contents
Set objTextStream = objFSO.OpenTextFile(strFileName, fsoForReading)
SendKeys objTextStream.ReadAll
objTextStream.close
Set objTextStream = Nothing
Else
'The file did not exist
SendKeys "was not found."
End If
'Clean up
Set objFSO = Nothing
End Sub
Please help. Thanks!

It looks like I needed some more libraries before it would work.
I added Microsoft WMI Scripting Library, OLE Automation, VBA 6, and Visual Basic Runtime Objections. I'm not sure which one fixed it.

Related

VBA Read a texts files: permission denied

I have a folder contain texts files . The text is presented as below :
NAME Number Mail Date
xx 1 zz //
and I want to write a vba code that read all the text files and search for an information "NAME" to replace it with "name"and then save the modifications .
I did the code below , but I have an error 70 permission denied in Set f = FSO.OpenTextFile(Fichier, forWriting, True) ,
could you help me ?
Sub Sample()
dim fso=createobject("scripting.filesystemObject")
dim f
dim path as string
dim file_txt as string
path= "C:\Users\Folder\Fileshere\"
file_txt= Dir(path & "*.*")
Do While Len(file_txt) > 0
'Set objfile = FSO.CreateTextFile(path & file_txt)
Set f = FSO.OpenTextFile(file_txt, ForReading)
While Not f.AtEndOfStream
Namechange = f.ReadAll
Wend
Namechange = Replace(Namechange , "NAME", "name")
Set f = FSO.OpenTextFile(file_txt, forWriting, True)
f.Write Namechange
file_txt=dir()
loop
end sub
I'd rewrite using a bit more of the FileSystemObject functionality rather than using Dir() personally, but that's open to your own choice. The key issue I think you are having is that you have opened the file for reading and then immediately tried to open it for writing while the TextStream object is still in memory, and locking the file. This is why you are getting "Permission denied". To quote from a TechNet Article:
Opening Text Files
Working with text files is a three-step process.
Before you can do anything else, you must open the text file. This can
be done either by opening an existing file or by creating a new text
file. (When you create a new file, that file is automatically opened
and ready for use.) Either approach returns a reference to the
TextStream object. After you have a reference to the TextStream
object, you can either read from or write to the file. However, you
cannot simultaneously read from and write to the same file. In other
words, you cannot open a file, read the contents, and then write
additional data to the file, all in the same operation. Instead, you
must read the contents, close the file, and then reopen and write the
additional data. When you open an existing text file, the file can be
opened either for reading or for writing. When you create a new text
file, the file is open only for writing, if for no other reason than
that there is no content to read. Finally, you should always close a
text file. Although this is not required (the file will generally be
closed as soon as the script terminates), it is good programming
practice.
My code should work for your requirements. I've removed the While loop from the middle as if you are using ReadAll then you don't need to loop over the text.
Sub MySub()
Dim fso
Set fso = CreateObject("scripting.filesystemObject")
Dim file, folder
Dim path As String
Dim file_txt As String
path = "C:\users\folders\fileshere\"
Set folder = fso.GetFolder(path)
For Each file In folder.Files
Set file = fso.OpenTextFile(file.Path, 1)
Namechange = file.ReadAll
file.Close
Namechange = Replace(Namechange, "NAME", "name")
Set file = fso.OpenTextFile(file.Path, 2, True)
file.Write Namechange
file.Close
Next
End Sub
If you have any difficulties or would like further explanation of the above, let me know.
Some minor changes and it worked for me. Please change the path as per your own requirement in following code:
Sub change_txt()
Dim fso As Object
Set fso = CreateObject("scripting.filesystemObject")
Dim f
Dim path As String
Dim file_txt As String
path = "D:\Folder\Fileshare\"
file_txt = Dir(path & "*.*")
Do While Len(file_txt) > 0
'Set objfile = FSO.CreateTextFile(path & file_txt)
Set f = fso.opentextfile(path & file_txt, 1)
While Not f.AtEndOfStream
Namechange = f.ReadAll
Wend
Namechange = Replace(Namechange, "NAME", "name")
Set f = fso.opentextfile(path & file_txt, 2)
f.Write Namechange
file_txt = Dir()
Loop
End Sub

Adding data to a specific column in a text file

I was wondering if there's a way in Access VBA to open a text file, and append data to the end of each line, at a specific column / space?
Basically, I need to open the text file and place a character at column # 300 of each line in the file (which is after all of the data).
I know I could just import the data into Access, add the column, and then export it, but for business reasons I'm trying to avoid this.
Thanks!
You can accomplish this using the Microsoft Scripting Runtime library. Add a reference to that library in your VBA project.
Here is a procedure that will append a delimiter (I've used a comma in my sample) to the end of each record in the text file.
Private Const DELIMITER As String = "," 'this is the text file delimiter that will add a column
Private Const FILE_PATH As String = "C:\temp\" 'this is the directory where the text file resides
Private Sub AppendColumnToTextFile()
Dim fso As New FileSystemObject
Dim readStream As Scripting.TextStream
Dim writeStream As Scripting.TextStream
'this is the name of the text file that needs a column appended
Dim currentFile As String: currentFile = "Test.csv"
'this is a temp text file where we'll re-write each record with an additional column
Dim tempFile As String: tempFile = "Test.New.csv"
'set the read/write streams
Set readStream = fso.OpenTextFile(FILE_PATH & currentFile, ForReading)
Set writeStream = fso.OpenTextFile(FILE_PATH & tempFile, ForWriting, True)
'read each line of the text file, and add a deilimeter at the end
Do While Not readStream.AtEndOfStream
writeStream.WriteLine readStream.ReadLine & DELIMITER
Loop
'close the streams
readStream.Close
writeStream.Close
fso.CopyFile FILE_PATH & tempFile, FILE_PATH & currentFile, True 'copy the temp file to the original file path
Kill FILE_PATH & tempFile 'delete the temp file
Set writeStream = Nothing
Set appendStream = Nothing
Set fso = Nothing
End Sub

How to remove the empty line that excel makes when creating a csv file using vba

As some of you probably know, excel creates an empty line at the end of CSV files. I'm looking for a solution that can remove/delete this line because I want to upload the CSV file to a different program, which can't handle this empty line.
First I thought it was the way I created the CSV file, but after spending hours searching for a solution, I found out that it's a bug.
Does anybody have a solution to this problem, removing the last line in a CSV file using VBA?
Try calling this Sub to kill the last line of the csv-file. You have to insert the path into the code:
Sub KillLastLine()
Dim fso As New FileSystemObject
Dim ts As TextStream
Dim filecontent As String
Dim myFile As File
Set myFile = fso.GetFile("YourCSVPathHere")
Set ts = myFile.OpenAsTextStream(ForReading)
While Not ts.AtEndOfStream
filecontent = filecontent & ts.ReadLine & vbCrLf
Wend
Set ts = myFile.OpenAsTextStream(ForWriting)
ts.Write Left(filecontent, Len(filecontent) - 1)
ts.Close
End Sub
Sub ZUtil_TextFile_FindReplace(FilePath As String, strOld As String, strNew As String)
'PURPOSE: Modify Contents of a text file using Find/Replace
'SOURCE: www.TheSpreadsheetGuru.com
Dim TextFile As Integer
Dim FileContent As String
'Determine the next file number available for use by the FileOpen function
TextFile = FreeFile
'Open the text file in a Read State
Open FilePath For Input As TextFile
'Store file content inside a variable
FileContent = Input(LOF(TextFile), TextFile)
'Clost Text File
Close TextFile
'Find/Replace
FileContent = Replace(FileContent, strOld, strNew)
FileContent = Replace(FileContent, "^(?:[\t ]*(?:\r?\n|\r))+", "")
If Right(FileContent, 2) = Chr(13) & Chr(10) Then
FileContent = Left(FileContent, Len(FileContent) - 2)
End If
'Determine the next file number available for use by the FileOpen function
TextFile = FreeFile
'Open the text file in a Write State
Open FilePath For Output As TextFile
'Write New Text data to file
Print #TextFile, FileContent
'Close Text File
Close TextFile
'MsgBox "ZUtil_TextFile_FindReplace TERMINADO"
End Sub

How can I edit a line in a file opened with FileSystemObject in VBA?

I'm looping through an input file and using the readline command to read each line, check it for various criteria, then I want to make changes based on the result. Here is a very simple version of what I'm trying to do:
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFile = objFSO.OpenTextFile(strFileLoc, 1)
Do While Not objFile.AtEndOfStream
strLineRead = objFile.readline
if strLineRead Like "*text to change*" Then
'Some code to change the line
end if
Loop
What I've been doing is saving the entire file to a string called strFileText, and then using a Replace function to replace the strLineRead within that string with the changed version. Something like this:
strFileText = Replace(strFileText, strLineRead, strNewLine)
and then write that entire string to a new text file.
The problem is, sometimes I might have a line where it's entire text is "NC", and then doing a find/replace on the entire file for "NC" changes more than just the one line.
So is there a command in the FileSystemObject, while on a certain line, to be able to alter the file directly? I'm thinking something like a "writeline" command.
Have these private subs somewhere in your file and on an event, call them. First call replace_text and fill it with the requirements. See my sample code.
Private Sub Command3_Click()
Dim sFileName As String
Dim fileSys As Variant
' Edit as needed
sFileName = Me.FileList.Value
Set fileSys = CreateObject("Scripting.FileSystemObject")
Replace_Text sFileName, "bad text", "good text", fileSys
End Sub
Private Sub Replace_Text(targetFile As String, targetText As String, replaceText As String, fileSys As Variant)
If Right(targetFile, 3) = "filepath extension you want (example: xml or doc etc.)" Then
Update_File targetFile, targetText, replaceText, fileSys
Else
MsgBox "You did not select the right file. Please try again."
End If
End Sub
Private Sub Update_File(fileToUpdate As String, targetText As String, replaceText As String, fileSys As Variant)
Dim tempName As String
Dim tempFile As Variant
Dim file As Variant
Dim currentLine As String
Dim newLine As String
'creates a temp file and outputs the original files contents but with the replacements
tempName = fileToUpdate & ".tmp"
Set tempFile = fileSys.CreateTextFile(tempName, True)
'open the original file and for each line replace any matching text
Set file = fileSys.OpenTextFile(fileToUpdate)
Do Until file.AtEndOfStream
currentLine = file.ReadLine
newLine = Replace(currentLine, targetText, replaceText)
'write to the new line containing replacements to the temp file
tempFile.WriteLine newLine
Loop
file.Close
tempFile.Close
'delete the original file and replace with the temporary file
fileSys.DeleteFile fileToUpdate, True
fileSys.MoveFile tempName, fileToUpdate
End Sub

using Application.FileDialog to rename a file in VBA

Using VBA. My script moves a file into a directory. If that filename already exists in the target directory, I want the user to be prompted to rename the source file (the one that's being moved) before the move is executed.
Because I want the user to know what other files are in the directory already (so they don't choose the name of another file that's already there), my idea is to open a FileDialog box listing the contents of the directory, so that the user can use the FileDialog box's native renaming capability. Then I'll loop that FileDialog until the source file and target file names are no longer the same.
Here's some sample code:
Sub testMoveFile()
Dim fso As FileSystemObject
Dim file1 As File
Dim file2 As File
Dim dialog As FileDialog
Set fso = New FileSystemObject
fso.CreateFolder "c:\dir1"
fso.CreateFolder "c:\dir2"
fso.CreateTextFile "c:\dir1\test.txt"
fso.CreateTextFile "c:\dir2\test.txt"
Set file1 = fso.GetFile("c:\dir1\test.txt")
Set file2 = fso.GetFile("c:\dir2\test.txt")
Set dialog = Application.FileDialog(msoFileDialogOpen)
While file1.Name = file2.Name
dialog.InitialFileName = fso.GetParentFolderName(file2.Path)
If dialog.Show = 0 Then
Exit Sub
End If
Wend
file1.Move "c:\dir2\" & file1.Name
End Sub
But when I rename file2 and click 'OK', I get an error:
Run-time error '53': File not found
and then going into the debugger shows that the value of file2.name is <File not found>.
I'm not sure what's happening here--is the object reference being lost once the file's renamed? Is there an easier way to let the user rename from a dialog that shows all files in the target directory? I'd also like to provide a default new name for the file, but I can't see how I'd do that using this method.
edit: at this point I'm looking into making a UserForm with a listbox that gets populated w/ the relevant filenames, and an input box with a default value for entering the new name. Still not sure how to hold onto the object reference once the file gets renamed, though.
Here's a sample of using Application.FileDialog to return a filename that the user selected. Maybe it will help, as it demonstrates getting the value the user provided.
EDIT: Modified to be a "Save As" dialog instead of "File Open" dialog.
Sub TestFileDialog()
Dim Dlg As FileDialog
Set Dlg = Application.FileDialog(msoFileDialogSaveAs)
Dlg.InitialFileName = "D:\Temp\Testing.txt" ' Set suggested name for user
' This could be your "File2"
If Dlg.Show = -1 Then
Dim s As String
s = Dlg.SelectedItems.Item(1) ` Note that this is for single-selections!
Else
s = "No selection"
End If
MsgBox s
End Sub
Edit two: Based on comments, I cobbled together a sample that appears to do exactly what you want. You'll need to modify the variable assignments, of course, unless you're wanting to copy the same file from "D:\Temp" to "D:\Temp\Backup" over and over. :)
Sub TestFileMove()
Dim fso As FileSystemObject
Dim SourceFolder As String
Dim DestFolder As String
Dim SourceFile As String
Dim DestFile As String
Set fso = New FileSystemObject
SourceFolder = "D:\Temp\"
DestFolder = "D:\Temp\Backup\"
SourceFile = "test.txt"
Set InFile = fso.GetFile(SourceFolder & SourceFile)
DestFile = DestFolder & SourceFile
If fso.FileExists(DestFile) Then
Dim Dlg As FileDialog
Set Dlg = Application.FileDialog(msoFileDialogSaveAs)
Dlg.InitialFileName = DestFile
Do While True
If Dlg.Show = 0 Then
Exit Sub
End If
DestFile = Dlg.Item
If Not fso.FileExists(DestFile) Then
Exit Do
End If
Loop
End If
InFile.Move DestFile
End Sub
Here's some really quick code that I knocked up but basically looks at it from a different angle. You could put a combobox on a userform and get it to list the items as the user types. Not pretty, but it's a start for you to make more robust. I have hardcoded the directory c:\ here, but this could come from a text box
Private Sub ComboBox1_KeyUp(ByVal KeyCode As MSForms.ReturnInteger,
ByVal Shift As Integer)
Dim varListing() As Variant
Dim strFilename As String
Dim strFilePart As String
Dim intFiles As Integer
ComboBox1.MatchEntry = fmMatchEntryNone
strFilePart = ComboBox1.Value
strFilename = Dir("C:\" & strFilePart & "*.*", vbDirectory)
Do While strFilename <> ""
intFiles = intFiles + 1
ReDim Preserve varListing(1 To intFiles)
varListing(intFiles) = strFilename
strFilename = Dir()
Loop
On Error Resume Next
ComboBox1.List() = varListing
On Error GoTo 0
ComboBox1.DropDown
End Sub
Hope this helps. On error resume next is not the best thing to do but in this example stops it erroring if the variant has no files