Macro VBA, can't get "SaveAs" to function - excel

I have a process that I run on sets of workbooks. I'm trying to modify the filetype when I close the file. I'm trying to tack it onto the end of the process before closing each workbook. Right now, the opened file is in .xlsb. I'm trying to save it in basically any other format (.xsls, etc.)
Whenever I run the Macro the "SaveAs" command errors out. I've tried everything I can think of to have it just save the file with the same name, different filetype, but no luck.
What am I doing wrong?
Application.ScreenUpdating = False
Application.DisplayAlerts = False
Path = ThisWorkbook.Sheets(1).Range("H6")
If Right(Path, 1) <> "\" Then
Path = Path & "\"
End If
wsheet = ThisWorkbook.Sheets(1).Range("F10")
ThisWorkbook.Sheets(3).Range("A2:B20000").ClearContents
OutLn = 2
Line = 1
Do While ThisWorkbook.Sheets(2).Cells(Line, 1) <> ""
OpnFil = ThisWorkbook.Sheets(2).Cells(Line, 1)
Workbooks.Open fileName:=Path & OpnFil, UpdateLinks:=False
ScanLn = 12
Do While ThisWorkbook.Sheets(1).Cells(ScanLn, 5) <> ""
ThisWorkbook.Sheets(3).Cells(OutLn, 1) = OpnFil
Addr = ThisWorkbook.Sheets(1).Cells(ScanLn, 5)
ThisWorkbook.Sheets(3).Cells(OutLn, 2) = Workbooks(OpnFil).Sheets(wsheet).Range(Addr)
OutLn = OutLn + 1
ScanLn = ScanLn + 1
Loop
Workbooks(OpnFil).SaveAs fileName:=Workbooks(OpnFil).GetBaseName, FileFormat:=51
Workbooks(OpnFil).Close
Line = Line + 1
Loop
End Sub```

Backup Workbooks
Use variables to avoid (long) unreadable lines (parameters).
Option Explicit
Sub BackupWorkbooks()
Dim swb As Workbook: Set swb = ThisWorkbook
Dim dFolderPath As String: dFolderPath = swb.Sheets(1).Range("H6").Value
If Right(dFolderPath, 1) <> "\" Then
dFolderPath = dFolderPath & "\"
End If
Dim dwsName As String: dwsName = swb.Sheets(1).Range("F10").Value
Application.ScreenUpdating = False
swb.Sheets(3).Range("A2:B" & swb.Sheets(3).Rows.Count).ClearContents
Dim OutLn As Long: OutLn = 2
Dim Line As Long: Line = 1
Dim dwb As Workbook
Dim dOldName As String
Dim dOldPath As String
Dim dNewPath As String
Dim dAddr As String
Dim ScanLn As Long
Do While swb.Sheets(2).Cells(Line, 1) <> ""
dOldName = swb.Sheets(2).Cells(Line, 1)
dOldPath = dFolderPath & dOldName
Set dwb = Workbooks.Open(Filename:=dOldPath, UpdateLinks:=False)
ScanLn = 12
Do While swb.Sheets(1).Cells(ScanLn, 5).Value <> ""
swb.Sheets(3).Cells(OutLn, 1).Value = dOldName
dAddr = swb.Sheets(1).Cells(ScanLn, 5).Value
swb.Sheets(3).Cells(OutLn, 2).Value _
= dwb.Worksheets(dwsName).Range(dAddr).Value
OutLn = OutLn + 1
ScanLn = ScanLn + 1
Loop
dNewPath = Left(dOldPath, InStrRev(dOldPath, ".") - 1) & ".xlsx"
' Or if you insist:
'dNewPath = dFolderPath & CreateObject("Scripting.FileSystemObject") _
.GetBaseName(dOldName) & ".xlsx"
Application.DisplayAlerts = False
dwb.SaveAs Filename:=dNewPath, FileFormat:=xlOpenXMLWorkbook ' 51
Application.DisplayAlerts = True
dwb.Close
Line = Line + 1
Loop
Application.ScreenUpdating = True
MsgBox "Backups created.", vbInformation, "Backup Workbooks"
End Sub

Related

Loop Through Excel Files and See if a Specific Cell Is Blank

I inherited VBA code that has not worked since my work updated our version of Excel.
The original code looped through all Excel files in a specific folder.
If data in specific cells was blank or a 0, would rename the whole workbook so I would know what files to delete after the fact.
This is the original code. I don't need it to do all of this anymore.
This is part one:
Sub AllFilesWeekly()
Dim folderPath As String
Dim filename As String
Dim wb As Workbook
folderPath = "C:\Users\" & (Environ$("Username")) & "\Desktop\Process Production\" 'change to suit
If Right(folderPath, 1) <> "\" Then folderPath = folderPath + "\"
filename = Dir(folderPath & "*.xlsx")
Do While filename <> ""
Application.ScreenUpdating = False
Set wb = Workbooks.Open(folderPath & filename)
'Call a subroutine here to operate on the just-opened workbook
Call getmetrics
On Error Resume Next
If Not ActiveWorkbook.Name Like "Audit Hub Report Distribution*" Then
ActiveWorkbook.Close
End If
filename = Dir
Loop
Application.ScreenUpdating = True
End Sub
The second part:
Sub getmetrics()
Dim cell As Range
Dim procstring As String, wbname As String
'Dim OQAYTD As String
Dim OQAMTD As String
Dim ORLYTD As String
Dim ORLMTD As String
Dim DR As String
Dim Audits As Long
Dim permonth As String, peryear As String, permonthrl As String, peryearrl As String
Dim RS As Worksheet, AD As Worksheet, QD As Worksheet, ws As Worksheet, YN As Boolean
For Each ws In Worksheets
If ws.Name = "Audit Detail" Then
YN = True
End If
Next ws
If YN = True Then
ActiveWorkbook.Sheets(2).Name = ("Rep Summary")
Set RS = ActiveWorkbook.Sheets("Rep Summary")
Set AD = ActiveWorkbook.Sheets("Audit Detail")
Set QD = ActiveWorkbook.Sheets("Question Detail")
With Sheets("Process Summary")
For Each cell In Range(Range("A3"), Range("A9999").End(xlUp))
If cell.Value = "Record Level YTD" Then
ORLYTD = Range(cell.Address).Offset(0, 1).Value
Else
If cell.Value = "YTD Quality Average" Then
OQAYTD = Range(cell.Address).Offset(0, 1).Value
Else
If cell.Value = "Record Level Quality Average" Then
ORLMTD = Range(cell.Address).Offset(0, 1).Value
Else
If cell.Value = "Quality Average" Then
OQAMTD = Range(cell.Address).Offset(0, 1).Value
Else
If cell.Value = "Audits" Then
Audits = Range(cell.Address).Offset(0, 1).Value
End If
End If
End If
End If
End If
Next cell
End With
wbname = Left(ActiveWorkbook.Name, Len(ActiveWorkbook.Name) - 4)
peryear = VBA.Format(OQAYTD, "Percent")
permonth = VBA.Format(OQAMTD, "Percent")
peryearrl = VBA.Format(ORLYTD, "Percent")
permonthrl = VBA.Format(ORLMTD, "Percent")
DR = Right(Sheets("Process Summary").Range("A2").Value, Len(Sheets("Process
Summary").Range("A2").Value) - 12)
RS.Range(RS.Range("A1"), RS.Range("IV1").End(xlToLeft)).AutoFilter
RS.Range(RS.Range("A1"), RS.Range("IV1").End(xlToLeft)).EntireColumn.AutoFit
AD.Range(AD.Range("A1"), AD.Range("IV1").End(xlToLeft)).AutoFilter
AD.Range(AD.Range("A1"), AD.Range("IV1").End(xlToLeft)).EntireColumn.AutoFit
QD.Range(QD.Range("A1"), QD.Range("IV1").End(xlToLeft)).AutoFilter
QD.Range(QD.Range("A1"), QD.Range("IV1").End(xlToLeft)).EntireColumn.AutoFit
Application.DisplayAlerts = False
procstring = wbname & "|" & permonth & "|" & Audits & "|" & peryear & "|" & permonthrl & "|" &
peryearrl & "|" & DR ' & "|" & Users
Debug.Print procstring
Else
Application.DisplayAlerts = False
Dim AWN As String
AWN = ActiveWorkbook.FullName
Debug.Print "Not Audited: " & ActiveWorkbook.Name
ActiveWorkbook.SaveAs "C:\Users\" & (Environ$("Username")) & "\Desktop\Process Production\Delete -" & Second(Now)
Kill AWN
ActiveWorkbook.Close savechanges:=True
Application.DisplayAlerts = True
End If
End Sub
All I need to do is look at cell D3 on the "Process Summary" tab.
If the value in that space is "0.00%", rename the workbook to delete and loop on until all workbooks are looked at.
I do not need to screen print all the extra numbers any more.
Build a Collection of filenames that match the criteria and then use it to rename the files.
Option Explicit
Sub AllFilesWeekly()
Dim folderPath As String, filename As String
Dim wb As Workbook, ws As Worksheet
Dim col As Collection, n As Long
Set col = New Collection
folderPath = "C:\Users\" & (Environ$("Username")) & "\Desktop\Process Production\" 'change to suit
If Right(folderPath, 1) <> "\" Then folderPath = folderPath + "\"
' scan folder
filename = Dir(folderPath & "*.xlsx")
Do While filename <> ""
Set wb = Workbooks.Open(folderPath & filename, True, True) ' update links, readonly
For Each ws In wb.Sheets
If ws.Name = "Process Summary" Then
If Format(ws.Range("D3"), "0.00%") = "0.00%" Then
col.Add wb.Name
End If
End If
Next
wb.Close
n = n + 1
filename = Dir
Loop
' result
MsgBox "Files scanned = " & n & vbCrLf & _
"To delete = " & col.Count, vbInformation, folderPath
' rename
If col.Count > 0 Then
If MsgBox("Continue to rename ?", vbYesNo) = vbYes Then
For n = 1 To col.Count
Name folderPath & col(n) As folderPath & "delete_" & col(n)
Next
MsgBox "Rename done"
End If
End If
End Sub

Double loop - cycling through subfolders and files for consolidation

I am a bit stuck with finishing the script below.
I got to this point and it does the basic thing I need it to do but it does need a bit of tweaking to get perfect.
It does the following: 1-pickup and prep master output file; 2- open each file in folder 'xls' and copy data from the designated sheet at the end of the master output file; 3-final edit of the master file; 4-save master file with name based on the input archives.
Where I need help is and was unable to fix up is: I want the script to cycle through subfolders in 'xls' folder and create a single master for each subfolder in 'xls' collecting data from files in that subfolder and name it after subfolder.
I understand I need another loop for subfolders but I am not really good with dirs in vba. Would this require a major overhaul?
Sub Joiner()
'Application.EnableCancelKey = xlDisabled
Dim folderPath As String
Dim FileNAME As String
Dim wb As Workbook
Dim Masterwb As Workbook
Dim sh As Worksheet
Dim NewSht As Worksheet
Dim FindRng As Range
Dim PasteRow As Long
Dim DayVar As String
Dim RangeVar As Variant
Dim LastRow As Long
Dim Targetsh As Worksheet
Dim RecordsCount As Long
' set master workbook
Workbooks.Open FileNAME:="C:\TA\output\Master Template.xlsx"
Set Masterwb = Workbooks("Master Template.xlsx")
Set Targetsh = Masterwb.Sheets("Data")
With ActiveWorkbook.Sheets("Data")
.Range("A1").FormulaR1C1 = "SysTime"
.Range("B1").FormulaR1C1 = "Seq#"
.Range("C1").FormulaR1C1 = "A1"
.Range("D1").FormulaR1C1 = "F2"
.Range("E1").FormulaR1C1 = "F3"
.Range("F1").FormulaR1C1 = "T4"
.Range("G1").FormulaR1C1 = "T5"
.Range("H1").FormulaR1C1 = "T6"
.Range("I1").FormulaR1C1 = "T7"
.Range("J1").FormulaR1C1 = "T8"
.Range("K1").FormulaR1C1 = "A9"
.Range("A1:K1").Font.Bold = True
.Range("A1:K1").Interior.ColorIndex = 19
.Range("L1").FormulaR1C1 = "Date"
.Range("M1").FormulaR1C1 = "Date/Seq#"
End With
folderPath = "C:\TA\xls\" 'contains folder path
If Right(folderPath, 1) <> "\" Then folderPath = folderPath & "\"
Application.ScreenUpdating = False
FileNAME = Dir(folderPath & "*.xls*")
Do While FileNAME <> ""
Set wb = Workbooks.Open(folderPath & FileNAME)
'DayVar = Left(Right(wb.Name, 13), 8)
LastRow = wb.Sheets("Cleaned").Range("A1").End(xlDown).Row
RangeVar = wb.Sheets("Cleaned").Range("A2:K" & LastRow)
Targetsh.Range("A" & Rows.Count).End(xlUp)(2).Resize(UBound(RangeVar, 1), UBound(RangeVar, 2)) = RangeVar
wb.Close False
Exit_Loop:
Set wb = Nothing
FileNAME = Dir
Loop
Application.ScreenUpdating = True
With Masterwb.Sheets("Data")
.Range(Range("A2"), Range("A2").End(xlDown)).NumberFormat = "dd/mm/yyyy hh:mm:ss"
End With
LastRow = ActiveWorkbook.Sheets("Data").Range("A1").End(xlDown).Row
With ActiveWorkbook.Sheets("Data")
.Range("L2").FormulaR1C1 = "=INT(C1)"
.Range("M2").FormulaR1C1 = "=C12&""-""&C2"
End With
Range("L2").AutoFill Destination:=Range("L2" & ":L" & LastRow)
With ActiveSheet
.Columns("L:L").Cells = .Columns("L:L").Cells.Value
End With
Range("M2").AutoFill Destination:=Range("M2" & ":M" & LastRow)
With ActiveSheet
.Columns("M:M").Cells = .Columns("M:M").Cells.Value
End With
With Masterwb.Sheets("Data")
.Range(Range("L2"), Range("L2").End(xlDown)).NumberFormat = "dd/mm/yyyy"
End With
'Name the master output based on id
Dim FirstName As String
Dim InterName As String
Dim FinalName As String
Dim FilePath As String
FirstName = Dir("C:TA\Input\*.cab", vbNormal)
InterName = "Master Template " & Right(Left(FirstName, 12), 4)
'MsgBox FirstName
'MsgBox InterName
FilePath = "C:\TA\output"
ActiveWorkbook.SaveAs FileNAME:=FilePath & "\" & InterName & ".xlsx", _
FileFormat:=51, CreateBackup:=False
'
End Sub
Thank you for any advice.
With this code you can list excel files in a folder and subfolders
Sub ListSubfoldersFile() ' only one level subfolders
arow = 2
Set objFSO = CreateObject("Scripting.FileSystemObject")
mFolder = "F:\Download\" ' path to change
Set mainFolder = objFSO.GetFolder(mFolder)
StrFile = Dir(mFolder & "*.xls*")
Do While Len(StrFile) > 0
Cells(arow, 1).Value = mFolder & StrFile
arow = arow + 1
StrFile = Dir
Loop
For Each mySubFolder In mainFolder.subfolders
StrFile = Dir(mySubFolder & "\*.xls*")
Do While Len(StrFile) > 0
Cells(arow, 1).Value = mySubFolder & "\" & StrFile
arow = arow + 1
StrFile = Dir
Loop
Next
End Sub
Thank you Patel!
I used your solution to complement my current vba snippet.
It may be a bit clunky but it does what I need it to do.
Thank you.
Posting a solution below for the benefit of the community.
Sub MassJoiner()
'this is a version of joiner with subfolders
'Application.EnableCancelKey = xlDisabled
Dim folderPath As String
Dim FileNAME As String
Dim wb As Workbook
Dim Masterwb As Workbook
Dim sh As Worksheet
Dim NewSht As Worksheet
Dim FindRng As Range
Dim PasteRow As Long
Dim DayVar As String
Dim RangeVar As Variant
Dim LastRow As Long
Dim Targetsh As Worksheet
Dim RecordsCount As Long
Dim StrFile As String
Dim mFolder As String
Dim BatchCount As Long
Dim ID As String
Set objFSO = CreateObject("Scripting.FileSystemObject")
mFolder = "D:\TA\TEST\" ' path to change
Set mainFolder = objFSO.GetFolder(mFolder)
StrFile = Dir(mFolder & "*.xls*")
BatchCount = 0
Workbooks.Open FileNAME:="C:\TA\output\Master Template.xlsx"
For Each mySubFolder In mainFolder.subfolders
StrFile = Dir(mySubFolder & "\*.xls*")
Do While Len(StrFile) > 0
Set Masterwb = Workbooks("Master Template.xlsx")
Set Targetsh = Masterwb.Sheets("Data")
With ActiveWorkbook.Sheets("Data")
.Range("A1").FormulaR1C1 = "SysTime"
.Range("B1").FormulaR1C1 = "Seq#"
.Range("C1").FormulaR1C1 = "A1"
.Range("D1").FormulaR1C1 = "F2"
.Range("E1").FormulaR1C1 = "F3"
.Range("F1").FormulaR1C1 = "T4"
.Range("G1").FormulaR1C1 = "T5"
.Range("H1").FormulaR1C1 = "T6"
.Range("I1").FormulaR1C1 = "T7"
.Range("J1").FormulaR1C1 = "T8"
.Range("K1").FormulaR1C1 = "A9"
.Range("A1:K1").Font.Bold = True
.Range("A1:K1").Interior.ColorIndex = 19
.Range("L1").FormulaR1C1 = "Date"
.Range("M1").FormulaR1C1 = "Date/Seq# pair"
End With
'FileNAME = Dir(folderPath & "*.xls*")
'Do While FileNAME <> ""
Set wb = Workbooks.Open(mySubFolder & "\" & StrFile)
'DayVar = Left(Right(wb.Name, 13), 8)
LastRow = wb.Sheets("Cleaned").Range("A1").End(xlDown).Row
RangeVar = wb.Sheets("Cleaned").Range("A2:K" & LastRow)
Targetsh.Range("A" & Rows.Count).End(xlUp)(2).Resize(UBound(RangeVar, 1), UBound(RangeVar, 2)) = RangeVar
wb.Close False
'Exit_Loop:
' Set wb = Nothing
' FileNAME = Dir
'Loop
StrFile = Dir
Loop
With Masterwb.Sheets("Data")
.Range(Range("A2"), Range("A2").End(xlDown)).NumberFormat = "dd/mm/yyyy hh:mm:ss"
End With
LastRow = ActiveWorkbook.Sheets("Data").Range("A1").End(xlDown).Row
With ActiveWorkbook.Sheets("Data")
.Range("M2").FormulaR1C1 = "Date/Seq# pair"
.Range("m2").FormulaR1C1 = "=C12&""-""&C2"
End With
Range("L2").AutoFill Destination:=Range("L2" & ":L" & LastRow)
With ActiveSheet
.Columns("L:L").Cells = .Columns("L:L").Cells.Value
End With
Range("M2").AutoFill Destination:=Range("M2" & ":M" & LastRow)
With ActiveSheet
.Columns("M:M").Cells = .Columns("M:M").Cells.Value
End With
With Masterwb.Sheets("Data")
.Range(Range("l2"), Range("l2").End(xlDown)).NumberFormat = "dd/mm/yyyy"
End With
'Name the master output based on job id
Dim FirstName As String
Dim InterName As String
Dim FinalName As String
Dim FilePath As String
FirstName = mySubFolder
InterName = "Master Template " & Right(FirstName, 4)
ID = Right(FirstName, 4)
'MsgBox FirstName
'MsgBox InterName
FilePath = "C:\TA\output"
ActiveWorkbook.SaveAs FileNAME:=FilePath & "\" & InterName & ".xlsx", _
FileFormat:=51, CreateBackup:=False
ActiveWorkbook.Close False
BatchCount = BatchCount + 1
Application.Speech.Speak "Batch job" & BatchCount & "finalized. ID" & ID
Workbooks.Open FileNAME:="C:\output\Master Template.xlsx"
Next
Application.ScreenUpdating = True
End Sub

modify macro to make it run faster

Who can help with this macro?
It's merging csv files into one.
csv files can be more than 500 and its running slow.
By the way it's taiking all data in csv file (2 rows). it will work for me if macro can take just second row from file..
Any ideas?
Option Explicit
Sub ImportCSV65()
Dim strSourcePath As String
Dim strDestPath As String
Dim strFile As String
Dim strData As String
Dim x As Variant
Dim Cnt As Long
Dim r As Long
Dim c As Long
Application.Calculation = xlCalculationManual
Application.ScreenUpdating = False
'Change the path to the source folder accordingly
strSourcePath = Worksheets("Tarpinis").Range("AJ8").Value
If Right(strSourcePath, 1) <> "\" Then strSourcePath = strSourcePath & "\"
strFile = Dir(strSourcePath & "*.csv")
Sheets("+65").Select
Application.ScreenUpdating = False
Do While Len(strFile) > 0
Cnt = Cnt + 1
If Cnt = 1 Then
r = 1
Else
r = Cells(Rows.Count, "A").End(xlUp).Row + 1
End If
Open strSourcePath & strFile For Input As #1
If Cnt > 1 Then
Line Input #1, strData
End If
Do Until EOF(1)
Line Input #1, strData
x = Split(strData, ",")
For c = 0 To UBound(x)
Cells(r, c + 1).Value = Trim(x(c))
Next c
r = r + 1
Loop
Close #1
Name strSourcePath & strFile As strSourcePath & strFile
strFile = Dir
Loop
Application.ScreenUpdating = True
If Cnt = 0 Then _
MsgBox "No CSV files were found...", vbExclamation
Application.ScreenUpdating = False
End Sub
How about the following, it will read the second line from each CSV file in the given folder and write that line in the Sheet +65:
Option Explicit
Sub ImportCSV65()
Dim strSourcePath As String
Dim strDestPath As String
Dim strFile As String
Dim strData As String
Dim x As Variant
Dim Cnt As Long
Dim r As Long
Dim c As Long
Dim counter As Long
Dim ws As Worksheet: Set ws = Sheets("+65")
Application.Calculation = xlCalculationManual
Application.ScreenUpdating = False
counter = 0
'Change the path to the source folder accordingly
strSourcePath = Worksheets("Tarpinis").Range("AJ8").Value
If Right(strSourcePath, 1) <> "\" Then strSourcePath = strSourcePath & "\"
strFile = Dir(strSourcePath & "*.csv")
Do While Len(strFile) > 0
Open strSourcePath & strFile For Input As #1
Do Until EOF(1)
Line Input #1, strData
r = ws.Cells(Rows.Count, "A").End(xlUp).Row + 1
counter = counter + 1
If counter = 2 Then 'counter to get only second line
x = Split(strData, ",")
For c = 0 To UBound(x)
ws.Cells(r, c + 1).Value = Trim(x(c))
Next c
r = r + 1
Exit Do
End If
Loop
Close #1
Name strSourcePath & strFile As strSourcePath & strFile
strFile = Dir
counter = 0 'reset counter before next file
Loop
Application.ScreenUpdating = True
End Sub
The only obvious place that I can see that could be done better is the loop that writes the trimmed values into the cells.
If you must trim each value, then you'll still need to loop through the array and Trim it:
For c = 0 To UBound(x)
x(c) = Trim(x(c))
Next c
But to write to the cells, you can speed things up by writing the array directly to the range:
Cells(r, 1).Resize(1, UBound(x) + 1).Value = x
You might also gain a little bit of time by qualifying the destination sheet, preferably as a With.
So the whole thing would look like this:
Sub ImportCSV65()
Dim strSourcePath As String
Dim strDestPath As String
Dim strFile As String
Dim strData As String
Dim x As Variant
Dim Cnt As Long
Dim r As Long
Dim c As Long
Application.Calculation = xlCalculationManual
Application.ScreenUpdating = False
'Change the path to the source folder accordingly
strSourcePath = Worksheets("Tarpinis").Range("AJ8").Value
If Right(strSourcePath, 1) <> "\" Then strSourcePath = strSourcePath & "\"
strFile = Dir(strSourcePath & "*.csv")
With Sheets("+65")
.Select
Application.ScreenUpdating = False
Do While Len(strFile) > 0
Cnt = Cnt + 1
If Cnt = 1 Then
r = 1
Else
r = .Cells(.Rows.Count, "A").End(xlUp).Row + 1
End If
Open strSourcePath & strFile For Input As #1
If Cnt > 1 Then
Line Input #1, strData
End If
Do Until EOF(1)
Line Input #1, strData
x = Split(strData, ",")
For c = 0 To UBound(x)
x(c) = Trim(x(c))
Next c
.Cells(r, 1).Resize(1, UBound(x) + 1).Value = x
r = r + 1
Loop
Close #1
Name strSourcePath & strFile As strSourcePath & strFile
strFile = Dir
Loop
End With
Application.ScreenUpdating = True
If Cnt = 0 Then _
MsgBox "No CSV files were found...", vbExclamation
Application.ScreenUpdating = False
End Sub
Workbooks.Open Filename:=strSourcePath & strFile, Format:=2
This code will open csv file as excel type.
And get data as variant vlaue and will fill your sheet by variant value.
Sub ImportCSV65()
Dim strSourcePath As String
Dim strDestPath As String
Dim strFile As String
Dim strData As String
Dim Ws As Worksheet, rngT As Range
Application.Calculation = xlCalculationManual
Application.ScreenUpdating = False
'Change the path to the source folder accordingly
strSourcePath = Worksheets("Tarpinis").Range("AJ8").Value
If Right(strSourcePath, 1) <> "\" Then strSourcePath = strSourcePath & "\"
strFile = Dir(strSourcePath & "*.csv")
Set Ws = Sheets("+65")
Application.ScreenUpdating = False
With Ws
Do While Len(strFile) > 0
Workbooks.Open Filename:=strSourcePath & strFile, Format:=2
With ActiveWorkbook.ActiveSheet
vDB = .UsedRange
End With
ActiveWorkbook.Close
Set rngT = .Range("a" & Rows.Count).End(xlUp)(2)
rngT.Resize(UBound(vDB, 1), UBound(vDB, 2)) = vDB
strFile = Dir
Loop
End With
Application.ScreenUpdating = False
End Sub

Error when importing csv file

I have a macro that imports csv-files into sheets with the same name in a workbook. All the csv files end with ".csv" except for one file which ends with ".CSV". The macro is importing the csv files that end with ".csv" fine. But when it encounters the csv file with ".CSV" it adds a new sheet. I think it's a matter of deactiviting the case sensivity (and I've tried) but I'm not sure. Here's the code:
Private Sub importOrUpdate(opr$)
Dim csvFile, csvArr
Dim wsCSV As Worksheet, wsImport As Worksheet
Dim importFolder$, cnt%, i%
Dim csvName$, idx%, arr, shName$
Dim processed$
U.Start
processed = "|"
csvArr = selectFiles
For i = 0 To UBound(csvArr)
'Workbooks.Open csvArr(i), False, True
Call importToTempSheet(csvArr(i))
Set wsCSV = Tempsheet
idx = InStrRev(csvArr(i), "\") + 1
csvName = Mid(csvArr(i), idx)
csvName = Replace(csvName, ".csv", "")
arr = Split(csvName, "_")
If UBound(arr) = 2 Then
shName = arr(1) & "_" & arr(2)
Else
shName = csvName
End If
On Error Resume Next
Set wsImport = ThisWorkbook.Sheets(shName)
On Error GoTo 0
If wsImport Is Nothing Then
ThisWorkbook.Sheets.Add before:=Sheet14
Set wsImport = ActiveSheet
wsImport.Tab.Color = 5296274
wsImport.Name = shName
Call import(wsCSV, wsImport)
ElseIf opr = "Update" Then
Call update(wsCSV, wsImport)
ElseIf InStr(1, processed, "|" & shName & "|", vbTextCompare) > 0 Then
Call update(wsCSV, wsImport)
Else
Call import(wsCSV, wsImport)
End If
Call updateFormula(wsImport)
processed = processed & shName & "|"
cnt = cnt + 1
'wsCSV.Parent.Close False
Next
Sheet14.Activate
U.Finish
MsgBox cnt & " files imported/updated", vbInformation
End Sub
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Sub importToTempSheet(filePath)
Dim lRow&
Tempsheet.Cells.Clear
Dim wsCSV As Worksheet
Workbooks.Open filePath, False, True
Set wsCSV = ActiveWorkbook.Sheets(1)
lRow = wsCSV.Cells(Rows.Count, "A").End(xlUp).Row
wsCSV.Range("A1:A" & lRow).Copy
Tempsheet.Range("A1").PasteSpecial xlPasteValues
Application.CutCopyMode = False
wsCSV.Parent.Close
Tempsheet.Range("A1:A" & lRow).TextToColumns Tempsheet.Range("A1"), xlDelimited, xlTextQualifierNone, False, False, True, False, False
With Tempsheet
.Range("A:A").NumberFormat = "m/d/yyyy"
convertToDate .Range("A2", .Cells(Rows.Count, "A").End(xlUp))
End With
End Sub
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Private Function selectFiles()
With Application.FileDialog(msoFileDialogFilePicker)
.Title = "Select CSV Files"
.ButtonName = "Select"
.AllowMultiSelect = True
.Filters.Clear
.Filters.Add "Excel Files", "*.csv"
.InitialFileName = ThisWorkbook.Path & "\"
.Show
If .SelectedItems.Count = 0 Then
End
Else
Dim csvArr, i%
ReDim csvArr(.SelectedItems.Count - 1)
For i = 1 To .SelectedItems.Count
csvArr(i - 1) = .SelectedItems(i)
Next
selectFiles = csvArr
End If
End With
End Function
The issue is with the replace
try..
csvName = Replace(LCase(csvName), ".csv", "")
or use two replaces...
csvName = Replace(csvName, ".csv", "")
csvName = Replace(csvName, ".CSV", "")

Split ExcelSheet after separator

I have an Excel file, in the first sheet I have on column A some text delimited by a separator, like this:
Column A
--------
Text line 1.1
Text line 1.2
Text line 1.3
***
Text line 2.1
Text line 2.2
Text line 2.3
***
Text line 3.1
I like to split the content after the *** separator and put each piece in a separate file with only one sheet. The name of the files should be the first line of the each section.
I need to be able to copy with the formatting, colors, etc.
This is the function but is not copying the formatting...
Private Function AImport(ThisWorkbook As Workbook) As Boolean
Dim height As Long
Dim fileName As String
Dim startLine As Long
Dim endLine As Long
Dim tmpWs As Worksheet
Dim AnError As Boolean
With ThisWorkbook.Worksheets(1) 'sheet name "Sheet1"
height = .Cells(.rows.Count, 2).End(xlUp).row
startLine = 6
nr = 1
For i = startLine + 1 To height
If InStr(.Cells(i, 2).Value, "***") > 0 Then
separate = i
a = Format(nr, "00000")
fileName = "File" & a
endLine = separate - 1
.rows(startLine & ":" & endLine).Copy
Set tmpWs = ThisWorkbook.Worksheets.Add
tmpWs.Paste
tmpWs.Select
tmpWs.Copy
Application.DisplayAlerts = False
ActiveWorkbook.SaveAs fileName:=ThisWorkbook.path & "\Output\" & fileName & " .xls", FileFormat:=xlExcel8, CreateBackup:=False 'xlOpenXMLWorkbookMacroEnabled
ActiveWorkbook.Close
tmpWs.Delete
'update next start line
startLine = separate + 1
nr = nr + 1
End If
Next i
End With
If AnError Then
MsgBox "Errors detected in " & ThisWorkbook.Name & "! Check LogFile.txt file for details. Execution stopped!", vbExclamation, inputWb.Name
AImport = False
Else:
Application.StatusBar = "Workbook check succesfully completed. Executing macro..."
AImport = True
End If
ThisWorkbook.Close
End Function
Just give out a workable solution, surely not a good one
Sub testing()
Dim height As Long
Dim fileName As String
Dim startLine As Long
Dim endLine As Long
Dim tmpWs As Worksheet
With ThisWorkbook.Worksheets("Sheet2") ' Input your sheet name here
height = .Cells(.Rows.Count, 1).End(xlUp).Row
startLine = 3
For i = 2 To height
If InStr(.Cells(i, 1).Value, "***") > 0 Then
separate = i
fileName = .Cells(startLine, 1).Value
endLine = separate - 1
.Rows(startLine & ":" & endLine).Copy
Set tmpWs = ThisWorkbook.Worksheets.Add
tmpWs.Paste
tmpWs.Select
tmpWs.Copy
Application.DisplayAlerts = False
' in the following line, replace the file path with your own
ActiveWorkbook.SaveAs fileName:="H:\" & fileName & " .xlsm", FileFormat:=xlOpenXMLWorkbookMacroEnabled, CreateBackup:=False
ActiveWorkbook.Close
tmpWs.Delete
'update next start line
startLine = separate + 1
End If
Next i
'handline the last section here
endLine = height
fileName = .Cells(startLine, 1).Value
.Rows(startLine & ":" & endLine).Copy
Set tmpWs = ThisWorkbook.Worksheets.Add
tmpWs.Paste
tmpWs.Select
tmpWs.Copy
Application.DisplayAlerts = False
ActiveWorkbook.SaveAs fileName:="H:\" & fileName & " .xlsm", FileFormat:=xlOpenXMLWorkbookMacroEnabled, CreateBackup:=False
ActiveWorkbook.Close
tmpWs.Delete
End With
End Sub
Something like this
This code dumps the files to single sheet csv files under a directory held by strDir, "C:temp" in this example
Sub ParseCOlumn()
Dim X
Dim strDir As String
Dim strFName As String
Dim strText As String
Dim lngRow As Long
Dim lngStart As Long
Dim objFSO As Object
Dim objFSOFile As Object
Set objFSO = CreateObject("scripting.filesystemobject")
strDir = "C:\temp"
X = Application.Transpose(Range([a1], Cells(Rows.Count, "A").End(xlUp)))
'test for first record not being "***"
lngStart = 1
If X(1) <> "***" Then
strFName = X(1)
lngStart = 2
End If
For lngRow = lngStart To UBound(X)
If X(lngRow) <> "***" Then
If Len(strText) > 0 Then
strText = strText & (vbNewLine & X(lngRow))
Else
strText = X(lngRow)
End If
Else
Set objFSOFile = objFSO.createtextfile(strDir & "\" & strFName & ".csv")
objFSOFile.write strText
objFSOFile.Close
strFName = X(lngRow + 1)
lngRow = lngRow + 1
strText = vbNullString
End If
Next
'dump last record
If X(UBound(X)) <> "***" Then
Set objFSOFile = objFSO.createtextfile(strDir & "\" & strFName & ".csv")
objFSOFile.write strText
End If
objFSOFile.Close
End Sub

Resources