I have an Excel VBA script that takes two files and performs a Relace function on one column. This all works fine if i step through it slowly. But if i run it without any breaks then it produces a file that still contains the characters that i replaced ?
I have added "Kill" file commands to ensure that i am creating new files, even my output file i am using a datestamp to ensure its a unique file then renaming it. But i then upload it to an FTP server as part of the script and when viewing what i have uploaded, it has the characters i removed ? even though when i view my output file before uploading, it doesnt ?????
Private Sub OutputFile()
Dim strNowDifferentiator As String
Dim strPath As String
Dim AgentStr As String
Dim AccessTypeLong As Long
Dim ProxyNameStr As String
Dim ProxyBypassStr As String
Dim FlagsLong As Long
Dim InternetSessionLong As Long
Dim ServiceLong As Long
Dim ContextLong As Long
Dim FTPSessionLong As Long
Dim FailIfExistsBool As Boolean
Dim FlagsAndAttributesLong As Long
Dim SomeThingLong As Long
Dim MyInternetHandleLong As Long
Dim MyFTPHandleLong As Long
Dim SomeInteger As Integer
Dim FTPSuccessBool As Boolean ' Did the FTP download work?
AgentStr = "GreenTreeTest" ' can be whatever
AccessTypeLong = 0 ' zero appears to work fine
ProxyNameStr = "" ' nul works fine here
ProxyBypassStr = "" ' nul works fine here
FlagsLong = 0 ' zero appears to work fine
MyInternetHandleLong = InternetOpen(AgentStr, AccessTypeLong, ProxyNameStr, ProxyBypassStr, FlagsLong)
' MsgBox MyInternetHandleLong
'MyInternetHandleLong is obtained above
ServiceLong = 1 ' this for the FTP service (2 = gopher, 3 = http)
FlagsLong = 0 ' 0 appears to work fine here
ContextLong = 0 ' 0 appears to work fine here
MyFTPHandleLong = InternetConnect(MyInternetHandleLong, "mercury.ingrammicro.com", 21, "CDW_PRICEFILE", "XXXXX", ServiceLong, FlagsLong, ContextLong)
strNowDifferentiator = Replace(Replace(Now(), "/", " "), ":", "")
strPath = "\\Sov-fs3\Departmental\Supply Chain\Feeds\"
Application.DisplayAlerts = False
Call subUpdateProgressLabel("Producing the output file...")
'DeleteFile ("C:\temp\CDWFeed.csv")
DeleteFile (strPath & "CDWFeed.csv")
ThisWorkbook.Sheets("Output").Copy
'ActiveWorkbook.SaveAs Filename:="C:\temp\CDWFeed.csv", FileFormat:=xlCSV, CreateBackup:=True
ActiveWorkbook.SaveAs Filename:=strPath & "CDWFeed" & strNowDifferentiator & ".csv", FileFormat:=xlCSV, CreateBackup:=True
ActiveWorkbook.Close SaveChanges:=False
Name strPath & "CDWFeed" & strNowDifferentiator & ".csv" As strPath & "CDWFeed.csv"
Call FtpDeleteFile(MyFTPHandleLong, "CDWFeed.csv")
Application.DisplayAlerts = True
Sheets("Output").Cells.Clear
Call subUpdateProgressLabel("Uploading file to Ingram fTP...")
'removed SHELL as doesnt work well within CITRIX
'Shell ("ftp -s:" & Chr(34) & "\\Sov-fs3\Departmental\Supply Chain\Feeds\script.txt" & Chr(34) & " mercury.ingrammicro.com")
Call FtpUpload("\\Sov-fs3\Departmental\Supply Chain\Feeds\CDWFeed.csv", "CDWFeed.csv", "mercury.ingrammicro.com", 21, "CDW_PRICEFILE", "XXXXXX")
End Sub
Related
I'm using a PowePoint Macro-enabled client (.PPTM) to gather survey data. When a user completes the survey, I'd like the .PPTM file to write the survey-complete date to an Excel file (via an Excel .App object).
The .PPTM and .XLSX files are both in the same SharePoint folder (access permissions are all correct). The .PPTM client can access the .XLSX file and load data, but attempts to write data back have no effect. The .XLSX file is merely a blank file with only 1 worksheet.
Have used both Excel .app objects and Excel worksheet objects to try to write data via '[object].Value = variable' syntax. Have tried both .Range and .Cell methds, but no luck with either one. The statements execute without error, but no data shows up in the target (addressed) cell.
I'm attaching a demo code block with all key aspects of this task. Is there something that's missing here? or is there some idio-syncratic limit that keeps an Excel .App object from writing data to an Excel file? All comments and feedback greatly appreciated.
Sub TEST()
Debug.Print Chr(10) & "|--TEST--|" & Chr(10)
Dim filePath As String, fileName As String
Dim fileTabName As String
Dim DataFile As Excel.Application ' process support var
Dim DataFile_Tab As Worksheet ' process support var
Dim results_Row As Integer, results_Col As Integer
Dim date_Stamp As String
'---------------------------------------------
' Assign FilePath, FileName, FileTabName
filePath = "https://[ SharePoint folder path here ]/"
fileName = "Test_Target.xlsx?web=1"
fileTabName = "Target"
'---------------------------------------------
' Establish connection to Excel Data File
Set DataFile = New Excel.Application
DataFile.Workbooks.Open _
filePath & fileName, _
True, _
True ' filePath & fileName & fileTabName, _
Set DataFile_Tab = DataFile.Worksheets(fileTabName)
date_Stamp = Format(Now(), "dd/mm/yyyy")
results_Row = 2
results_Col = 2
Debug.Print "DataFile_Tab.Cells(" & results_Row & ", " & results_Col & ").Value = '" & _
date_Stamp & "'"
DataFile_Tab.Cells(results_Row, results_Col) = date_Stamp
DataFile_Tab.Cells(results_Row, results_Col).Value = date_Stamp
'---------------------------------------------
' Terminate connection to Excel Data File
Set DataFile = Nothing
Set DataFile_Tab = Nothing
End Sub
You're opening the workbook in read-only mode (3rd parameter of Workbooks.Open), and never saving it. Try the following (untested).
Dim app As Excel.Application
Set app = New Excel.Application
Dim dataFile As Excel.Workbook
Set dataFile = app.Workbooks.Open(filePath & fileName, True)
Dim tabName As String
tabName = "Target"
Dim resultsRow As Long, resultsCol As Long
resultsRow = 2
resultsCol = 2
dataFile.Worksheets(tabName).Cells(resultsRow, resultsCol).Value = Date
dataFile.Save
dataFile.Close
app.Quit
I have found this VBA code and it works to remove the known password on one Excel workbook just fine.
Sub testPasswordRemoval()
Dim wb As Workbook
Set wb = Workbooks.Open(Filename:="C:\Temp\Book2.xlsm", Password:="pw")
wb.Password = ""
wb.SaveAs "C:\Temp\NewBook.xlsm"
End Sub
But, I have tried various tutorials and videos (many folks offering this) but none of them work to loop through a folder of .xlsx files (all with the same known password) and remove that same password.
I am not a VBA person, but have spent about 16 hours over the past three days trying to crack the code on this one. I have found several examples of looping over files in a directory, but none that enabled me to put the above code into them and loop and remove passwords.
Try this code, read the comments, and adjust it to fit your needs
Code:
Public Sub RemovePassLoopThroughFiles()
Dim targetWorkbook As Workbook
Dim filePath As String
Dim folderPath As String
Dim folderWildcard As String
Dim currentFileName As String
Dim currentFileExtension As String
Dim newFileName As String
Dim newfileNameSuffix As String
Dim currentPassword As String
Dim newPassword As String
' Adjust next lines to fit your needs
folderPath = "C:\Temp\" ' With slash at the end
folderWildcard = "*.xls*" ' You can change the suffix to open specific files
newfileNameSuffix = "_NoPassword"
currentPassword = "pw"
newPassword = ""
' Get the file path concat folder and wildcards
filePath = Dir(folderPath & folderWildcard)
Do While Len(filePath) > 0
' Open the workbook and set reference
Set targetWorkbook = Workbooks.Open(Filename:=filePath, Password:=currentPassword)
' Get current file extension
currentFileExtension = Right(filePath, Len(filePath) - InStrRev(filePath, "."))
' Get filename no extension
currentFileName = Left(filePath, InStrRev(filePath, ".") - 1)
' Build new fileName
newFileName = currentFileName & newfileNameSuffix & "." & currentFileExtension
' Set new password
targetWorkbook.Password = newPassword
' Save new file
targetWorkbook.SaveAs folderPath & newFileName
'Debug.Print filePath
filePath = Dir
targetWorkbook.Close True
Set targetWorkbook = Nothing
Loop
End Sub
Let me know if it works.
I'm writing a code to delete a log entry in a .csv file. The code starts with opening the .csv file, using Application.Match to return the row number, and then deleting that and closing the file again. The problems I'm experiencing are I get a type mismatch (my error handling is activated) OR (and here it gets weird) it works (a match is found, the row is deleted) but then the logfile is messed up - all data is one string in column a with either ";" or "," delimiters (this varies somehow, relevant note: I use Dutch language excel). Of course, this makes it impossible for the macro to find a match in any case.
I found that the type mismatch problems I'm experiencing will most likely be caused by the code not finding a match, and this is what I don't understand since I checked and doublechecked the input and the data in the logfile - by all means it simply should find a match. And sometimes it does find a match, deletes the row and messes up formatting. (NOTE: Mostly it does NOT find a match.)
I check data in the .csv file before running the macro. I have tried running the macro with the .csv file already opened. I have tried to Set the matchArray from outside the With. I have tried both sweet talking my laptop and a more aggressive approach, to no avail.
Sub DeleteRowFromFile(ByVal matchValue As String)
Dim filePath As String
Dim fileName As String
Dim fileType As String
Dim matchArray As Range
Dim rowToDelete As Variant
'Naming variables for flexibility
filePath = "C:\Users\Maxim\Documents\Log\"
fileName = "TestRegister"
fileType = ".csv"
Application.ScreenUpdating = False
Workbooks.Open (filePath & fileName & fileType)
With Workbooks(fileName).Worksheets(1)
Set matchArray = .Range("A:A") 'set range in the logfile
'Type mismatch here:
rowToDelete = Application.Match(matchValue, matchArray, 0)
If Not IsError(rowToDelete) Then
Rows(rowToDelete).Delete
Else:
MsgBox "Orderno. " & matchValue & " not found.", vbOKOnly + vbExclamation, "Error"
End If
End With
'Closing the log file
Workbooks(fileName).Close SaveChanges:=True
Application.ScreenUpdating = True
End Sub
Sub MatchAndDelete()
Dim matchValueRange As String
matchValueRange = ActiveWorkbook.Worksheets(1).Range("A1").Value
DeleteRowFromFile (matchValueRange)
End Sub
Footnote:
I'm a struggling enthusiast, I have a lot to learn. Sorry in advance if I have left out any crucial information for you to be of help, and thanks a lot for any and all help.
When you open or save a csv file using a VBA macro Excel will always use the standard (US English delimiters) while if you do the same via the user interface it will use the separators as defined in the Windows regional settings, which probably is ";" in your case.
You can check with .?application.International(xlListSeparator) in the immediate window of your VBEditor.
You can tell Excel to use a different separator, by e.g. adding sep=; as line 1 of your file. Hoever this entry is gone after opening the file. The following code - added before you open the csv file will add this:
Dim oFSo As Object
Dim oTxtFile As Object
Dim strData As String
Set oFSo = CreateObject("Scripting.FileSystemObject")
strData = oFSo.OpenTextFile(filePath & fileName & fileType, 1).ReadAll
Set oTxtFile = oFSo.OpenTextFile(filePath & fileName & fileType, 2)
oTxtFile.writeline "sep=;"
oTxtFile.writeline strData
oTxtFile.Close
You can save your changed file by using the Excel UserInterface Shortcuts via the Application.SendKeys thus achieving what you want:
Application.SendKeys ("^s") 'Save
Application.SendKeys ("^{F4}") 'Close
Dont run this code from the VBE Immeditate window as it will probabaly act on the wrong file!
The full code - just with an alternate way to make the requested change:
Sub DeleteRowFromFile(ByVal matchValue As String)
Dim filePath As String
Dim fileName As String
Dim fileType As String
Dim matchArray As Range
Dim rowToDelete As Variant
Dim oFSo As Object
Dim oTxtFile As Object
Dim strData As String
Dim content As Variant
Dim i As Long
'Naming variables for flexibility
filePath = "C:\Users\Maxim\Documents\Log\"
fileName = "TestRegister"
fileType = ".csv"
Application.ScreenUpdating = False
'Adding "sep =" ; as line 1 of the log file
Set oFSo = CreateObject("Scripting.FileSystemObject")
strData = oFSo.OpenTextFile(filePath & fileName & fileType, 1).ReadAll
Set oTxtFile = oFSo.OpenTextFile(filePath & fileName & fileType, 2)
oTxtFile.writeline "sep=;"
oTxtFile.writeline strData
oTxtFile.Close
'Open logfile
Workbooks.Open (filePath & fileName & fileType)
'Make your changes
With Workbooks(fileName).Worksheets(1)
content = .UsedRange.Value
For i = UBound(content, 1) To 1 Step -1
If content(i, 1) = matchValue Then
.Rows(i).Delete
End If
Next i
End With
'Closing the log file via Sendkeys using excel shortcuts
Application.SendKeys ("^s") 'Save
Application.SendKeys ("^{F4}") 'Close
Application.ScreenUpdating = True
I think that Match it is not required. Try this one.
Sub DeleteRowFromFile(ByVal matchValue As String)
Dim filePath As String
Dim fileName As String
Dim fileType As String
Dim matchArray As Range
Dim rowToDelete As Variant
'Naming variables for flexibility
filePath = "C:\Users\Maxim\Documents\Log\"
fileName = "TestRegister"
fileType = ".csv"
Application.ScreenUpdating = False
Workbooks.Open (filePath & fileName & fileType)
With Workbooks(fileName).Worksheets(1)
For i = .UsedRange.SpecialCells(xlCellTypeLastCell).Row To 1 Step -1
If .Cells(i, 1).Value2 = matchValue Then
.Cells(i, 1).EntireRow.Delete
End If
Next
End With
'Closing the log file
Workbooks(fileName & fileType).SaveAs Filename:= _
(filePath & fileName & fileType) _
, FileFormat:=xlCSVMSDOS, CreateBackup:=False 'Saving the file
Workbooks(fileName & fileType).Close 'Closing the file
Application.ScreenUpdating = True
End Sub
Hope it helps
I have looked at quite a lot of similar questions, but none of them seem to work for my specific issue.
I have a macro that saves my file with a new name if it encounters a file with the same name.
What keeps happening is that it saves the original file to the correct folder, but then when it encounters the file name the next time I save it, the instanced file gets saved to the same folder as the template rather than the folder that they should go to.
In the example below, my template file is saved in the "M:\Excel\" directory.
It saves the first "TEST" file into the "M:\Excel\SavedVersions\" directory since the file name doesn't exist yet.
Then when I run the macro again to have it automatically save an instanced version (ie - "TESTrev1"), it keeps saving the instanced versions to the "M:\Excel\" directory instead of saving it to the "SavedVersions" subfolder.
Not sure what needs to be changed or done differently to get the instanced versions to save to the correct folder.
Any help would be greatly appreciated!
Thanks in advance! :)
Sub TEST()
ActiveWorkbook.Save
ActiveWorkbook.SaveAs Filename:= _
GetNextAvailableName("M:\Excel\SavedVersions\TEST.xlsm")
End Sub
Function GetNextAvailableName(ByVal strPath As String) As String
With CreateObject("Scripting.FileSystemObject")
Dim strFolder As String, strBaseName As String, strExt As String, i As Long
strFolder = .GetParentFolderName("M:\Excel\SavedVersions\")
strBaseName = .GetBaseName("TEST")
strExt = .GetExtensionName(".xlsm")
Do While .FileExists(strPath)
i = i + 1
strPath = .BuildPath(strFolder, strBaseName & "rev" & i & "." & strExt)
Loop
End With
GetNextAvailableName = strPath
End Function
Your code was unnecessarily complex.
Try this simpler version.
Sub TEST()
ActiveWorkbook.Save
ActiveWorkbook.SaveAs fileName:= _
GetNextAvailableName("M:\Excel\SavedVersions\TEST.xlsm")
End Sub
Function GetNextAvailableName(ByVal strPath As String) As String
Dim i as Interger: i = 0
Do Until Len(Dir(strPath)) = 0
i = i + 1
strPath = "M:\Excel\SavedVersions\TESTrev" & i & ".xlsm"
Loop
GetNextAvailableName = strPath
End Function
Keep your code simple. If your path is constant then might as well define a variable for it so that it can be used whenever and whereever you want. This way if there is any change in the path, you have to make the change at only one place.
While saving the file, also specify the FileFormat parameter to avoid problems. You might want to read more about it HERE
Is this what you are trying?
Option Explicit
Const sPath As String = "M:\Excel\SavedVersions\"
Sub Sample()
Dim flName As String
flName = sPath & GetNextAvailableName()
ActiveWorkbook.Save
ActiveWorkbook.SaveAs Filename:=flName, _
FileFormat:=xlOpenXMLWorkbookMacroEnabled
End Sub
Function GetNextAvailableName() As String
Dim i As Integer: i = 1
Dim newFile As String
newFile = "TestRev" & i & ".xlsm"
Do Until Dir(sPath & newFile) = ""
i = i + 1
newFile = "TestRev" & i & ".xlsm"
Loop
GetNextAvailableName = newFile
End Function
I'm trying to save excel file into a specific path.
So basically, when I click the button, I'm creating a folder, and want to save the file inside that folder.
The created folder has the current month as name. I'm trying to save into that current month folder.
'Create folder as Month Name. Save filename as date inside "month".
Dim sDate As String = DateTime.Now.ToString("yyyy-MM-dd") & "_" & DateTime.Now.ToString("HH-mm-ss")
Dim sMonth As String = DateTime.Now.ToString("MMMM")
Dim sFolder = Application.StartupPath & "\Resources\Excel\"
My.Computer.FileSystem.CreateDirectory(sFolder & Format(sMonth))
Dim sfinal = Path.Combine(sFolder, sMonth)
xlSh.SaveAs(sfinal & Format(sDate) & ".xlsx")
xlApp.Workbooks.Close()
xlApp.Quit()
As it is, this code doesn't give me any errors. But instead of creating a folder named "March" <-current month and saving inside it, it saves the file in \Excel\ and it also creates folder in the same place.
you could use the following function (similar to .NET System.IO.Path.Combine)
Function PathCombine(path1 As String, path2 As String)
Dim combined As String
combined = path1
If Right$(path1, 1) <> Application.PathSeparator Then
combined = combined & Application.PathSeparator
End If
combined = combined & path2
PathCombine = combined
End Function
Hope this helps!
After long hours of excruciating pain, I've finally did it!
Apparently I was missing an "\"
Since "sMonth" became dynamic name, which later I wanted to use as path, and save files in that folder. I needed to simply put that "\" after sMonth, to tell it to save inside it.
Before I realize this... I've broken down, simplified the code as much as I could so I can logically connect the pieces. What I ended up with, is something slightly different. Now the SaveAS properly saves the file inside the new folder.
Dim sDate As String
sDate = DateTime.Now.ToString("yyyy-MM-dd") & "_" & DateTime.Now.ToString("HH-mm-ss")
Dim sMonth As String
sMonth = DateTime.Now.ToString("MMMM")
Dim sFileName As String
sFileName = sDate + ".xlsx"
Dim sFolder As String
sFolder = Application.StartupPath & "\Resources\Excel\"
Dim sfinal As String
sfinal = (sFolder & sMonth & "\") '<- this thingie here o.O
My.Computer.FileSystem.CreateDirectory(sFolder & Format(sMonth))
xlSh.SaveAs(sfinal & Format(sFileName))
xlApp.Workbooks.Close()
xlApp.Quit()
Thanks for the help.
You don't appear to actually be setting the save path to the created directory. Instead, I believe you're appending the month to the beginning of the file name in the xlSh.SaveAs(sFinal & Format(sDate) & ".xlsx"). Basically (though I'm not sure of the specific command) you need to navigate to the folder you created after you create it. Probably something to the format of
My.Computer.FileSystem.ChangeDirectory(sFolder & Format(sMonth))
though I don't know that that specific command actually exists as I wrote it.
To those who have been wondering wtf I was doing with all this, here is the full sub. And if anyone needs something similar. Thanks for the support. Problem has been resolved.
Private Sub Button_Click(sender As Object, e As EventArgs) Handles Button.Click
Dim xlApp As Excel.Application
Dim xlSh As Excel.Worksheet
xlApp = New Excel.Application
xlApp.Workbooks.Add()
xlSh = xlApp.Workbooks(1).Worksheets(1)
'Items from listbox1 to be exported into excel, second row, second column.
Dim row As Integer = 2
Dim col As Integer = 2
For i As Integer = 0 To ListBox1.Items.Count - 1
xlSh.Cells(row, col) = ListBox1.Items(i)
row = row + 1
Next
row += 1
col = 1
'Items from listbox2 to be exported into excel, second row, third column.
Dim row2 As Integer = 2
Dim col2 As Integer = 3
For i As Integer = 0 To ListBox2.Items.Count - 1
xlSh.Cells(row2, col2) = ListBox2.Items(i)
row2 = row2 + 1
Next
row2 += 1
col2 = 1
'Create folder as Month Name. Save filename as date inside that folder.
'Make filename be yyyy-MM-DD_HH-mm-ss
Dim sDate As String
sDate = DateTime.Now.ToString("yyyy-MM-dd") & "_" & DateTime.Now.ToString("HH-mm-ss")
'This will be used as name for the new folder.
Dim sMonth As String
sMonth = DateTime.Now.ToString("MMMM")
'Filename + extension.
Dim sFileName As String
sFileName = sDate + ".xlsx"
'This is the path.
Dim sFolder As String
sFolder = Application.StartupPath & "\Resources\Excel\"
'This is the path combined with sMonth to make the final path.
Dim sfinal As String
sfinal = (sFolder & sMonth & "\")
'Check if folder with the name sMonth already exists.
If Dir(sFolder, vbDirectory) = sMonth Then
'If it exist, then simply save the file inside the folder.
xlSh.SaveAs(sfinal & Format(sFileName))
Else
'If it doesn't exist:
'This is the creation of sMonth folder, inside "\excel\.
My.Computer.FileSystem.CreateDirectory(sFolder & Format(sMonth))
'This saves the excel file at path sfinal, with filename of sFileName
xlSh.SaveAs(sfinal & Format(sFileName))
End If
'Close everything.
xlApp.Workbooks.Close()
xlApp.Quit()
End Sub
I find this method to be much easier.
Create a FileSystemObject and use BuildPath Method, like so:
Set fs = CreateObject("Scripting.FileSystemObject")
skPath = fs.BuildPath(ActiveDocument.Path, "Survival Story of Sword King")
Attention: ActiveDocument.Path is current directory in Word and does not work in excel or other. for excel it would be ActiveWorkbook.Path
My point is some methods or namespace are application specific.