VBA copyfile it it doesn't exist - vba

I have a list of file in 2 columns A and B.
A column is the source the B
B column is the destination
The code below copy file from source to destination. But if the destination exists it give me errors. What is the condition so that if it find that it exists it will not do anyting ??
What is the wrong with the code ?
Sub FC_Copy()
Dim ClientsFolderDestination
Dim fso As New FileSystemObject
Dim rep_destination
Dim source
lastrow = ThisWorkbook.Worksheets("XClients").Cells(Application.Rows.Count, 1).End(xlUp).Row
For i = 5 To lastrow
source = ThisWorkbook.Worksheets("XClients").Cells(i, 1).Value
ClientsFolderDestination= ThisWorkbook.Worksheets("XClients").Cells(i, 2).Value
If fso.FileExists(source) Then
rep_destination = Left(ClientsFolderDestination, Len(ClientsFolderDestination) - Len(fso.GetFileName(ClientsFolderDestination)) - 1)
If Not fso.FolderExists(rep_destination) Then
sub_rep = Split(rep_destination, "\")
myrep = sub_rep(0)
If Not fso.FolderExists(myrep) Then
MkDir myrep
End If
For irep = 1 To UBound(sub_rep)
myrep = myrep & "\" & sub_rep(irep)
If Not fso.FolderExists(myrep) Then
MkDir myrep
End If
Next
End If
fso.CopyFile source, ClientsFolderDestination
End If
Next i
end sub

Try this.
This doesn't use Microsoft Scripting Runtime Library.
It uses one common function to check for existence of file and folder
It caters for destination paths like C:\Sample.xlsx
Code
Sub FC_Copy()
Dim ws As Worksheet
Dim source As String, Destination As String, sTemp As String
Dim lRow As Long, i As Long, j As Long
Dim MyAr As Variant
Set ws = ThisWorkbook.Sheets("XClients")
With ws
'~~> Find Last Row
lRow = .Range("A" & .Rows.Count).End(xlUp).Row
For i = 5 To lRow
source = .Range("A" & i).Value
Destination = .Range("B" & i).Value
MyAr = Split(Destination, "\")
'~~> This check is required for destination paths like C:\Sample.xlsx
If UBound(MyAr) > 1 Then
sTemp = MyAr(0)
For j = 1 To UBound(MyAr)
sTemp = sTemp & "\" & MyAr(j)
If Not FileFolderExists(sTemp) = True Then MkDir sTemp
Next j
End If
If Not FileFolderExists(Destination) Then FileCopy source, Destination
Next i
End With
End Sub
Public Function FileFolderExists(strFullPath As String) As Boolean
On Error GoTo Whoa
If Not Dir(strFullPath, vbDirectory) = vbNullString Then FileFolderExists = True
On Error GoTo 0
Whoa:
End Function

If Not fso.FileExists(ClientsFolderDestination) Then
fso.CopyFile source, ClientsFolderDestination
End If
or if you want to overwrite the destination file
fso.CopyFile source, ClientsFolderDestination, True
CopyFile Method

Related

Output in a different workbook

I've created a tool and the below macro copies all .csv files into a excel sheet. I want the data to be copied to the "Consol.xlsx" file that I created. The current code copies the data in the tool not the "Consol.xlsx" file. I am unable to update the code so that the data gets copied correctly.
Below is my code:
Sub Button_click2()
Call AddNew
Call ImportCSVsWithReference
End Sub
Sub AddNew()
Application.DisplayAlerts = False
Dim thisWb As Workbook
Set thisWb = ActiveWorkbook
Workbooks.Add
ActiveWorkbook.SaveAs Filename:=thisWb.path & "\Consol.xlsx"
Application.DisplayAlerts = True
End Sub
Sub ImportCSV()
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.ScreenUpdating = False
'Change the path to the source folder accordingly
strSourcePath = Application.ActiveWorkbook.path
If Right(strSourcePath, 1) <> "\" Then strSourcePath = strSourcePath & "\"
'Change the path to the destination folder accordingly
strDestPath = Application.ActiveWorkbook.path
If Right(strDestPath, 1) <> "\" Then strDestPath = strDestPath & "\"
strFile = Dir(strSourcePath & "*.csv")
Do While Len(strFile) > 0
Cnt = Cnt + 1
r = Cells(Rows.count, "A").End(xlUp).Row + 1
Open strSourcePath & strFile For Input As #1
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 strDestPath & strFile
strFile = Dir
Loop
Application.ScreenUpdating = True
If Cnt = 0 Then _
MsgBox "No CSV files were found...", vbExclamation
End Sub
Well it looks like you've got both of the pieces there. Your first subroutine saves a blank workbook called consol.xlsx.
Then, your second subroutine loops through the directory, opens each csv file, and copes it to some unspecified range.
What I would insert before your loop is:
Set wbkConsol = Workbooks.Open(thisWorkbook.path & "\Consol.xlsx")
Then, during your loop over the CSV files:
strFile = Dir(strSourcePath & "*.csv")
Do While Len(strFile) > 0
Cnt = Cnt + 1
r = Cells(Rows.count, "A").End(xlUp).Row + 1
Open strSourcePath & strFile For Input As #1
Do Until EOF(1)
Line Input #1, strData
' Set wshAdd = wbkConsol.Worksheets.Add() ' New ws in wbk
' wshAdd.Name = left(strFile, 31) ' First 31-chars of filename.
x = Split(strData, ",")
For c = 0 To UBound(x)
wshAdd.Cells(r, c + 1).Value = Trim(x(c))
Next c
r = r + 1
Loop
Close #1
Name strSourcePath & strFile As strDestPath & strFile
strFile = Dir()
Loop
As an added note: you could pass your workbook from your first sub to the second sub, by reference. That way, you won't have to open it up again. This would be by combining the button click into just a single command.
Sub1()
wbkConsol = workbooks.Add
Call sub2(wbkConsol)
End sub

copying data from a folder of workbooks into a single worksheet iteration through loop in VBA

I am trying to copy data from a couple of workbooks present in a folder into a single workbook. I am looping through the folder to fetch the data from the various workbooks but I need to paste the data spanning from A5:D5 in loop.
i.e A5:D5 in the destination sheet is one workbook's data in the folder, I need the other set of data to be copied into A6:D6 and so on for the number of workbooks in the folder. Please help me loop through this.
Private Sub CommandButton1_Click()
Dim wbk As Workbook
Dim Filename As String
Dim Path As String
Path = "D:\Macro_Demo\estimation_sheets\"
Filename = Dir(Path & "*.xls")
Set target = Workbooks.Open("D:\Macro_Demo\Metrics_Macro_dest")
'--------------------------------------------
'OPEN EXCEL FILES
Do While Len(Filename) > 0 'IF NEXT FILE EXISTS THEN
Set wbk = Workbooks.Open(Path & Filename)
target.Sheets("Metrics_Data").Range("A5").Value = wbk.Sheets("summary").Range("I5").Value
target.Sheets("Metrics_Data").Range("B5").Value = wbk.Sheets("summary").Range("I6").Value + wbk.Sheets("summary").Range("I7")
target.Sheets("Metrics_Data").Range("C5").Value = wbk.Sheets("summary").Range("I8").Value
target.Sheets("Metrics_Data").Range("D5").Value = wbk.Sheets("summary").Range("I9").Value
MsgBox Filename & " has opened"
wbk.Close True
Filename = Dir
Loop
MsgBox "Task complete!"
End Sub
Try this:
Private Sub CommandButton1_Click()
Dim wbk As Workbook, target As Workbook, excelFile As String, path As String, rw As Integer
path = "D:\Macro_Demo\estimation_sheets\"
excelFile = Dir(path & "*.xls")
rw = 5
Set target = Workbooks.Open("D:\Macro_Demo\Metrics_Macro_dest")
Do While excelFile <> ""
Set wbk = Workbooks.Open(path & excelFile)
With target.Sheets("Metrics_Data")
.Range("A" & rw) = wbk.Sheets("summary").Range("I5")
.Range("B" & rw) = wbk.Sheets("summary").Range("I6") + wbk.Sheets("summary").Range("I7")
.Range("C" & rw) = wbk.Sheets("summary").Range("I8")
.Range("D" & rw) = wbk.Sheets("summary").Range("I9")
End With
wbk.Close True
rw = rw + 1
excelFile = Dir
Loop
MsgBox "Task complete!"
End Sub
You need to find the next available row on your destination sheet, store that in a variable, and write the data relative to that cell. Like this
Private Sub CommandButton1_Click()
Dim shSource As Worksheet, shDest As Worksheet
Dim sFile As String
Dim rNextRow As Range
Const sPATH As String = "D:\Macro_Demo\estimation_sheets\"
'Open the destination workbook
Set shDest = Workbooks.Open("D:\Macro_Demo\Metrics_Macro_dest.xls").Worksheets("Metrics_Data")
sFile = Dir(sPATH & "*.xls")
Do While Len(sFile) > 0
Set shSource = Workbooks.Open(sPATH & sFile).Worksheets("summary")
'start at row 1000 and go up until you find something
'then go down one row
Set rNextRow = shDest.Cells(1000, 1).End(xlUp).Offset(1, 0)
'Write the values relative to rNextRow
With rNextRow
.Value = shSource.Range("I5").Value
.Offset(0, 1).Value = shSource.Range("I6").Value
.Offset(0, 2).Value = shSource.Range("I8").Value
.Offset(0, 3).Value = shSource.Range("I9").Value
End With
'Close the source
shSource.Parent.Close False
sFile = Dir
Loop
MsgBox "Done"
End Sub

Import data from different Workbooks VBA

I have a code see below to import data from different workbooks inside one folder. I try it and it works perfectly however I was wondering if someone could help me to improve it.
I explain: "zmaster.xlms" workbook is the one where all data are past in sheet one. In this same workbook in sheet2 i have a table like this:
Where the column "Excel Column code" is where the data should be past (in the "zmaster.xlms") and "Form Cell Code" correspond to the cells which should be copy from every workbooks (which are in the same file in my desktop).
Question: How To say to the macro to look at the table and copy the cell K26 and past it in the columnA of the zmaster file and loop until the end of the table?
Dim MyFile As String
Dim erow
Dim Filepath As String
Filepath = "C:\Desktop\New folder\"
MyFile = Dir(Filepath)
Do While Len(MyFile) > 0
If MyFile = "zmaster.xlsm" Then
Exit Sub
End If
Workbooks.Open (Filepath & MyFile)
' Range("A1:D1").Copy
ActiveWorkbook.Close
erow = Sheet1.Cells(Rows.Count, 1).End(xlUp).Offset(1, 0).Row
ActiveSheet.Paste Destination:=Worksheets("Sheet1").Range(Cells(erow, 1), Cells(erow, 4))
MyFile = Dir
Loop
End Sub
Thank you in advance for your help!
All you need to do is to loop through the cells in sheet 2 (zmaster.xlsm). Have a look at example code. Please, read comments.
[EDIT]
Code has been updated!
Option Explicit
'assuming that:
'- "Excel Column Code" is in column A
'- "Form Cell Code" is in column B
'in zmaster.xlsm!Sheet2
Sub UpdateData()
Dim sFile As String, sPath As String
Dim srcWbk As Workbook, dstWbk As Workbook
Dim srcWsh As Worksheet, dstWsh As Worksheet, infoWsh As Worksheet
Dim i As Long, j As Long, k As Long
On Error GoTo Err_UpdateData
Set dstWbk = ThisWorkbook
Set dstWsh = dstWbk.Worksheets("Sheet1")
Set infoWsh = dstWbk.Worksheets("Sheet2")
sPath = "C:\Desktop\New folder\"
sFile = Dir(sPath)
Do While Len(sFile) > 0
If sFile = "zmaster.xlsm" Then
GoTo SkipNext
End If
Set srcWbk = Workbooks.Open(sPath & sFile)
Set srcWsh = srcWbk.Worksheets(1)
i = 2
'loop through the information about copy-paste method
Do While infoWsh.Range("A" & i) <> ""
'get first empty row, use "Excel Column Code" to get column name
j = GetFirstEmpty(dstWsh, infoWsh.Range("A" & i))
'copy data from source sheet to the destination sheet
'use "Form Cell Code" to define destination cell
srcWsh.Range(infoWsh.Range("B" & i)).Copy dstWsh.Range(infoWsh.Range("A" & i) & j)
i = i + 1
Loop
srcwbk.Close SaveChanges:=False
SkipNext:
sFile = Dir
Loop
Exit_UpdateData:
On Error Resume Next
Set srcWsh = Nothing
Set dstWsh = Nothing
Set srcWbk = Nothing
Set dstWbk = Nothing
Exit Sub
Err_UpdateData:
MsgBox Err.Description, vbExclamation, Err.Number
Resume Exit_UpdateData
End Sub
'returns first empty row in a destination sheet based on column name
Function GetFirstEmpty(ByVal wsh As Worksheet, Optional ByVal sCol As String = "A") As Long
GetFirstEmpty = wsh.Range(sCol & wsh.Rows.Count).End(xlUp).Row + 1
End Function
At the moment you code
erow = Sheet1.Cells(Rows.Count, 1).End(xlUp).Offset(1, 0).Row
ActiveSheet.Paste Destination:=Worksheets("Sheet1").Range(Cells(erow, 1), Cells(erow, 4))
is simply copying columns A to D of the first row of data in the source worksheet to a new row in the destination worksheet.
I'm assuming that you still want to create a new single row, but that you want the table on sheet2 to define which cells are put into which column of the new row.
you need to write something like this (which is untested):
Sub YourCode()
Dim MyFile As String
Dim erow
Dim Filepath As String
Dim wbSource As Workbook
Dim wsSource As Worksheet
Dim wsDestination As Worksheet
Dim rngMapping As Range
Dim DestinationRow As Long
Dim cell As Range
Filepath = "C:\Desktop\New folder\"
MyFile = Dir(Filepath)
Set wsDestination = ActiveWorkbook.Sheet1
' Named range "MappingTableFirstColumn" is defined as having the first column in the sheet2 table and all the rows of the table.
Set rngMapping = ActiveWorkbook.Names("MappingTable").RefersToRange
Do While Len(MyFile) > 0
If MyFile = "zmaster.xlsm" Then
Exit Sub
End If
Set wbSource = Workbooks.Open(Filepath & MyFile)
Set wsSource = wbSource.Sheets("Sheet1")
DestinationRow = wsDestination.Cells(wsDestination.Rows.Count, 1).End(xlUp).Offset(1, 0).Row
For Each cell In rngMapping
wsDestination.Range(cell.Value & DestinationRow) = wsSource.Range(cell.Offset(0, 1)).Value
Next cell
MyFile = Dir
Loop
ActiveWorkbook.Close
End Sub

VB script to work for loading objects from local directory with specified names on Range B

I wanted to write a code for macro, that will load files from my local directory into excel sheet of Column say ("C"), the names on files should match names on Column ("B"). If any of the files doesn't find for the names given in column B it should skip that row of loading files and continues to next column. I'am difficulty in writing as I am new to VB. I tried somehow but, my script working to load files from directory and loading names. Please help!! thank you all,
Code:
Sub Insert_OLE_Object()
Dim mainWorkBook As Workbook
Set mainWorkBook = ActiveWorkbook
Set ActiveSheet = example1
Folderpath = "C:\Documents and Settings\my\Desktop\folder1"
Set fso = CreateObject("Scripting.FileSystemObject")
NoOfFiles = fso.GetFolder(Folderpath).Files.Count
Set listfiles = fso.GetFolder(Folderpath).Files
For Each fls In listfiles
Counter = Counter + 1
Range("B" & Counter).Value = fls.Name
strCompFilePath = Folderpath & "\" & Trim(fls.Name)
If strCompFilePath <> "" Then
Worksheets("Example1").OLEObjects.Add(Filename:=strCompFilePath, Link:=False, DisplayAsIcon:=True, IconIndex:=1, IconLabel:=strCompFilePath, Left:=20, Top:=40, Width:=150, Height:=10).Select
Sheets("example1").Activate
Sheets("example1").Range("C" & ((Counter - 1) * 3) + 1).Select
End If
Next
End Sub
Try this code:
Sub Insert_OLE_Object()
Dim ws As Worksheet
Dim rng As Range, c As Range
Dim strCompFilePath As String, Folderpath As String, fullpath As String
Dim obj As Object
Application.ScreenUpdating = False
'change to suit
Set ws = ThisWorkbook.Worksheets("Example1")
'change B1:B5 to suit
Set rng = ws.Range("B1:B5")
Folderpath = "C:\Documents and Settings\my\Desktop\folder1"
For Each c In rng
strCompFilePath = Dir(Folderpath & "\" & Trim(c.Value) & ".*")
'if file with this name found, embed it
If strCompFilePath <> "" Then
fullpath = Folderpath & "\" & strCompFilePath
Set obj = ws.OLEObjects.Add(Filename:=fullpath, Link:=False, _
DisplayAsIcon:=True, IconIndex:=1, _
IconLabel:=fullpath)
With obj
.Left = c.Offset(, 1).Left
.Top = c.Offset(, 1).Top
.Width = c.Offset(, 1).ColumnWidth
.Height = c.Offset(, 1).RowHeight
End With
End If
Next
Application.ScreenUpdating = True
End Sub

Run-time error '1004' Method 'Save' of object '_Workbook' failed

I got this error while running an VBA application. I think this error is related to the following line in my code
ActiveWorkbook.Save
This is the whole code.
LDate = Date
LDate = Mid(LDate, 4, 2)
If LDate > 8 Then
Sheets("a").Cells(13, "H").Value = Sheets("a").Cells(13, "H").Value + 1000
Else
Sheets("a").Cells(13, "H").Value = Sheets("a").Cells(13, "H").Value + 1
End If
ActiveWorkbook.Save
Can someone explain the cause of this error and how I can tackle it.
Please read below comments.
This is the subroutine that is getting executed when the first button is clicked.
Sub import()
Dim Filt As String
Dim FilterIndex As Integer
Dim Title As String
Dim FileName As Variant
Dim finalrow As Integer
Dim alldata As String
Dim temp As String
Dim oFSO As New FileSystemObject
Dim oFS As TextStream
'Filt = "Cst Files (*.txt),*.txt"
'Title = "Select a cst File to Import"
'FileName = Application.GetOpenFilename(FileFilter:=Filt, Title:=Title)
'If FileName = False Then
'MsgBox "No File Was Selected"
'Exit Sub
'End If
'Call TestReference
' Open the file dialog
Set diaFolder = Application.FileDialog(msoFileDialogFolderPicker)
diaFolder.AllowMultiSelect = False
diaFolder.Show
If diaFolder.SelectedItems.Count <> 0 Then
folderpath = diaFolder.SelectedItems(1)
folderpath = folderpath & "\"
'MsgBox diaFolder.SelectedItems(1)
Set diaFolder = Nothing
'RefreshSheet
On Error Resume Next
temp = folderpath & "*.txt"
sFile = Dir(temp)
Do Until sFile = ""
inputRow = Sheets("RawData").Range("A" & Rows.Count).End(xlUp).Row + 1
FileName = folderpath & sFile
Set oFS = oFSO.OpenTextFile(FileName)
Dim content As String
content = oFS.ReadAll
content = Mid(content, 4, Len(content) - 3)
With Sheets("RawData").Range("A" & inputRow)
.NumberFormat = "#"
.Value = content
End With
oFS.Close
Set oFS = Nothing
alldata = ""
finalrow = Sheets("RawData").Cells(Rows.Count, 1).End(xlUp).Row
Sheets("RawData").Activate
For i = inputRow To finalrow
alldata = alldata & Cells(i, "A").Value & " "
Cells(i, "A").Value = ""
Next i
Cells(inputRow, "B").Value = alldata
temp = StrReverse(FileName)
temp = Left(temp, InStr(1, temp, "\") - 1)
temp = StrReverse(temp)
temp = Left(temp, InStr(1, temp, ".") - 1)
Cells(inputRow, "A").Value = temp
Sheets("RawData").Cells(inputRow, "A").NumberFormat = "#"
sFile = Dir()
Loop
Else
MsgBox ("No Folder Selected")
End If
End Sub
How to make this code stop accessing the worksheet after executing this macro?
Although I think you should seriously consider refactoring your code, you should begin by referencing the correct workbook called by the .Save() Method.
Workbooks("Insert_Workbook_Name_Here.xlsm").Save
Make sure that the workbook name and extension (.xlsm, .xls, .xlsx) match the file you are actually trying to save.
This error happened in a macro that I wrote as well. I have this code to close a dialogue box.
Private Sub CancelButton_Click()
Unload Me
ThisWorkbook.Save
End
End Sub
I received the same error because the workbook that was being loaded was from a "last saved" copy due to an update reboot that happened while the original was open. Not sure how to avoid that in the future but thought it might be helpful to someone.