I'm reading multiple csv files into excel for some number crunching. The file reads appear to work with each excel column having the csv file name inserted for confirmation. Odd thing. Each csv file name is correctly inserted into the sheet, but the data is all the same as the first file.
Is there a way to flush / reset ..... something, so the next read file data actually is the next file?
Excel VBA code snippet:
Public Const sRawFilePath As String = "\\server1\Sample.RAW.Files\"
----------------
Sub ImportCSV()
Dim sFullFilePath, sFile As String
fFIle = FreeFile()
sFile = Dir(sRawFilePath & "*.csv")
sFullFilePath = sRawFilePath & sFile
While sFile <> ""
Open sFullFilePath For Input As fFIle
While Not EOF(fFIle)
Line Input #fFIle, sLine
""
"take the sLine string and separate the comma delimited values for insertion into columns "
"This part works fine"
""
Wend
Close fFIle
sFile = Dir()
Wend
End Sub
Stepping through the code I can confirm the next file is in the queue, but the read data is not representing the next file, just the first file, ... and always the first file even though 20 more files are read.
PS - This forum has been an amazing resource.
The problem is you define sFullFilePath which locks in the file that you're opening. So even though you're successfully looping through the files with Dir, you will only open the first one because you locked it in. Don't use that variable at all:
'Change this line
Open sFullFilePath For Input As fFIle
'To be this instead
Open sRawFilePath & sFile For Input As fFIle
Rather than executing Dir(sRawFilePath & "*.csv") in every call, you should just execute Dir in subsequent calls. The error causes you to re-read the first file again and again.
Related
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
I have an Excel sheet that pulls data from a folder full of .txt documents.
Last week Friday, it worked. Nothing changed. This week Monday, I get a Run-time error '53': File not found.
What's interesting, is that when I click "Debug" it highlights a line in my code, and when I mouse over the 'sFile' variable, it tells me the name of the file that it apparently can't find... but it could only know the name of it if it found it... And yes, I've verified, that file does exist.
The Excel sheet is in H:\My Documents\Loma CW3 Reports\
The data .txt files are in H:\My Documents\Loma CW3 Reports\Product Statistics\
The first 3 files that it should be pulling are:
- PR20180912T153019.txt
- PR20180913T070005.txt
- PR20180913T153002.txt
Like mentioned above, when I'm debugging the code and mouse-over "sFile" in the line "Open sFile For Input As #1", it tells me:
sFile = "PR20180912T153019.txt"
Which it could only know if it was successfully scanning the folder since I don't hardcode any of those file names in.
I have tried removing that file, renaming the file to a word like 'apple', checked to see if it became read-only (nope). I'm thrown for a loop here, because it worked as is last week, and nothing changed from when I opened it up this week and tried it.
Code below:
Private Sub CommandButton1_Click()
' Dim myFile As String
Dim text As String, textLine As String
Dim sFile As String, rowTarget As Long
rowTarget = 2
' myFile = Application.GetOpenFilename()
sFile = Dir("H:\My Documents\Loma CW3 Reports\Product Statistics\" & "*.txt*")
Do Until sFile = ""
Open sFile For Input As #1
Do Until EOF(1)
Line Input #1, textLine
text = text & textLine
Loop
Close #1
Do stuff here
rowTarget = rowTarget + 1
sFile = Dir()
text = ""
Loop
End Sub
I ended up specifying directory as a separate variable and appended the sFile name to it when opening the file.
Dim directory As String
directory = "H:\My Documents\Loma CW3 Reports\Product Statistics\"
sFile = Dir(directory & "*.txt*")
Do Until sFile = ""
Open (directory & sFile) For Input As #1
blah blah blah
Thanks #comintern
Whenever a specific Excel file is in use, I'd like to prevent anyone else editing it.
ie. "This file is currently being edited by John Dow, and it will now close".
I'm looking for something simple.
Any ideas?
Thank you,
D.
I'm going to add an answer to this which I'll have to say is nowhere near perfect (blatantly trying to avoid down-votes for trying to do something that isn't really necessary).
I just wanted to see if you could extract the name of the person that has it open - after all, it does normally give the name of the person who has it locked for editing when you first open a workbook.
When you open an Excel file a hidden lock file is created in the same folder. The lock file has the same name as the original with ~$ appended to the front of the file name.
I found you can't copy the lock file using the VBA FileCopy as you get a Permission denied error, but you can using the FileSystemObject CopyFile.
The thinking behind my method is to copy the lock file and change it to a text file. You can then pull the user name from it and compare it against the current user name - if it's different then report that and close the file.
Note - I wouldn't use this in a project as there seems to be a few places it can fall over, and Excel will generally tell you that someone else has it open anyway. It was more of a coding exercise.
Private Sub Workbook_Open()
Dim ff As Long
Dim sLockFile As String
Dim sTempFile As String
Dim oFSO As Object
Dim XLUser As String, LoggedUser As String
Dim fle As Object
sLockFile = ThisWorkbook.Path & Application.PathSeparator & "~$" & ThisWorkbook.Name
sTempFile = Replace(sLockFile, "~$", "") & "tmp.txt"
'Create copy of lock file as a text file.
Set oFSO = CreateObject("Scripting.FileSystemObject")
oFSO.CopyFile sLockFile, sTempFile, True
'Read the first line from the text file.
ff = FreeFile()
Open sTempFile For Input Lock Read As #ff
Line Input #1, XLUser
Close ff
'Remove the current user from the text.
'Need to check this so that it doesn't close because it sees the current user name.
XLUser = Replace(XLUser, Application.UserName, "")
'Extract name from text string.
'There is a double space in the InStr section.
'The double exclamation mark is a single character - I don't know the code though.
'Unicode U+0203C I think.
XLUser = Replace(Left(XLUser, InStr(XLUser, " ") - 1), "", "")
'Remove hidden attributes so temp file can be deleted.
Set fle = oFSO.GetFile(sTempFile)
fle.Attributes = 0
Kill sTempFile
'If there's still text then it's a user name - report it and close.
If Len(Trim(XLUser)) > 0 Then
MsgBox "Workbook is already open by " & XLUser
ThisWorkbook.Close SaveChanges:=False
End If
End Sub
Having put all that, this code is probably safer:
Private Sub Workbook_Open()
If ThisWorkbook.ReadOnly Then
MsgBox "Is opened in read only.", vbOKOnly
ThisWorkbook.Close SaveChanges:=False
End If
End Sub
I'm using code to open all the files in a folder that start with a particular prefix:
folder = "C:\Users\xxx\Documents\Exception Reports\"
pref = "blah blah prefix"
file = pref & "*.xls"
exPath = folder & file
filename = Dir(exPath)
Do While filename <> ""
Workbooks.Open (filename)
...
Workbooks(filename).Close SaveChanges:=False
filename = Dir()
Loop
The first time I run the code after opening the macro, I get "Sorry we couldn't find -filename-. Is it possible it was moved, renamed, or deleted?" But the -filename- it prints is the one I want it to open, and all I have specified is the prefix I want and the file extension, so it would seem to me like it's finding it just fine if it knows the full file name. Also if I put in a message box between declaring the filename variable and starting the Do While loop, the message box prints the correct filename that I want it to open.
If I save a new file into the folder and name it something like "AA.xls", and then just have the program loop through the folder (rather than specifying the prefix), and then go back and specify the prefix, it works just fine, and continues to work until I close the program and reopen, where the process starts all over. However, this process only works if I save a new file to that folder. If I try to leave the "AA.xls" file in the folder, I get the same error with that file that I get with the others.
Thanks for any input!
Try using a CMD approach and see if you get the same problem, if you do then it's more than likely a permissions issue:
Sub SO()
Const folder As String = "C:\Users\xxx\Documents\Exception Reports\"
Const pref As String = "blah blah prefix"
Dim file As String
Dim exPath As String
Dim fileName As Variant
file = pref & "*.xls": exPath = folder & file
For Each fileName In _
Filter(Split(CreateObject("WScript.Shell").Exec("CMD /C DIR """ & exPath & """ /B /A:-D").StdOut.ReadAll, vbCrLf), ".")
Workbooks.Open CStr(folder & fileName)
'// Do code here
Workbooks(fileName).Close False
Next fileName
End Sub
The title is messy, my apologies. Not sure the best way to word that, so if you a better suggestion, please.
The script I have works, but I'm having trouble keeping the leading zeros. I have tried to insert the .NumberFormat = "#", but I can only do that after I have created the file. I also tried adding the "'" at the leading zero when it puts the text into the file and it does add it, but doesn't apply it. It just keeps the "'" in front of the zero.
Suggestions? Thank you in advance!
Original number: 00099999 ----
Currently adds to file as: 99999 ----
If I add "'", it adds to file as: '00099999
Here's the snippet:
FName = i & "_INPUT" & ".csv"
If FName = False Then
Exit Sub 'user cancelled
End If
FNum = FreeFile
Open FName For Output Access Write As #FNum
For Each ir In range
If ir > 0 Then
strtest = ir
newnum = ExtractNumber(strtest)
End If
S = newnum & Chr(9) 'build each line
S = Left(S, Len(S) - 1) 'remove trailing tab
Print #FNum, S 'print to file
Next ir
Close #FNum
End If
How are you testing the CSV file? If you reopen it in Excel, it will remove the leading zeroes at that point - if you open it in Notepad they should still be there, assuming they were written to the file originally.