Firstly I am a newbie when it comes to coding, but am giving it a go to see how it can help me dig down into my data.
I am currently looking at capturing time-sheet data for different team members and copying it into a master summary workbook.
I recorded my macro and then re-organised things a bit to make the code cleaner (this may be where I went wrong). But now when I run my macro I get a Run-time error '9': Subscript out of range.
my code is as follows:
Option Explicit
Sub MergeAll()
' Open all Timesheets
Workbooks.Open Filename:= _
"S:\UFD\24 Reports\02 Time Keeping\PT Time Sheets\2016_JAMAL.xlsx"
Workbooks.Open Filename:= _
"S:\UFD\24 Reports\02 Time Keeping\PT Time Sheets\2016_LOKESH.xlsx"
Workbooks.Open Filename:= _
"S:\UFD\24 Reports\02 Time Keeping\PT Time Sheets\2016_NONI.xlsx"
Workbooks.Open Filename:= _
"S:\UFD\24 Reports\02 Time Keeping\PT Time Sheets\2016_RAJESH.xlsx"
Workbooks.Open Filename:= _
"S:\UFD\24 Reports\02 Time Keeping\PT Time Sheets\2016_SANTHOSH.xlsx"
Workbooks.Open Filename:= _
"S:\UFD\24 Reports\02 Time Keeping\PT Time Sheets\2016_7.xlsx"
Workbooks.Open Filename:= _
"S:\UFD\24 Reports\02 Time Keeping\PT Time Sheets\2016_8.xlsx"
Workbooks.Open Filename:= _
"S:\UFD\24 Reports\02 Time Keeping\PT Time Sheets\2016_9.xlsx"
' Activate and Copy Data
Windows("2016_JAMAL.xlsx").Activate
Range("G2:J2").Select
Selection.Copy
Windows("master.xlsm").Activate
Range("C2:F2").Select
ActiveSheet.Paste
Windows("2016_LOKESH.xlsx").Activate
Range("G2:J2").Select
Selection.Copy
Windows("master.xlsm").Activate
Range("C2:F2").Select
ActiveSheet.Paste
Windows("2016_NONI.xlsx").Activate
Range("G2:J2").Select
Selection.Copy
Windows("master.xlsm").Activate
Range("C2:F2").Select
ActiveSheet.Paste
Windows("2016_RAJESH.xlsx").Activate
Range("G2:J2").Select
Selection.Copy
Windows("master.xlsm").Activate
Range("C2:F2").Select
ActiveSheet.Paste
Windows("2016_SANTHOSH.xlsx").Activate
Range("G2:J2").Select
Selection.Copy
Windows("master.xlsm").Activate
Range("C2:F2").Select
ActiveSheet.Paste
Windows("2016_WARREN.xlsx").Activate
Range("G2:J2").Select
Selection.Copy
Windows("master.xlsm").Activate
Range("C2:F2").Select
ActiveSheet.Paste
Windows("2016_7.xlsx").Activate
Range("G2:J2").Select
Selection.Copy
Windows("master.xlsm").Activate
Range("C2:F2").Select
ActiveSheet.Paste
Windows("2016_8.xlsx").Activate
Range("G2:J2").Select
Selection.Copy
Windows("master.xlsm").Activate
Range("C2:F2").Select
ActiveSheet.Paste
Windows("2016_9.xlsx").Activate
Range("G2:J2").Select
Selection.Copy
Windows("master.xlsm").Activate
Range("C2:F2").Select
ActiveSheet.Paste
' Close all Timesheets
Windows("2016_JAMAL.xlsx").Activate
ActiveWindow.Close
Windows("2016_LOKESH.xlsx").Activate
ActiveWindow.Close
Windows("2016_NONI.xlsx").Activate
ActiveWindow.Close
Windows("2016_RAJESH.xlsx").Activate
ActiveWindow.Close
Windows("2016_SANTHOSH.xlsx").Activate
ActiveWindow.Close
Windows("2016_WARREN.xlsx").Activate
ActiveWindow.Close
Windows("2016_7.xlsx").Activate
ActiveWindow.Close
Windows("2016_8.xlsx").Activate
ActiveWindow.Close
Windows("2016_9.xlsx").Activate
ActiveWindow.Close
End Sub
Now I took out some code which was appearing in each line, after the Windows("filename").Activate line. This was:
ActiveWindow.SmallScroll Down:=-18
As I believe that this was only when I scrolled up to the correct place and depending on which was the active cell prior to saving each time, this would change.
I am out of ideas and any help would be much appreciated.
For the record, I have so far tried several different methods - including copying and pasting code from sites, following you tube tutorial videos, but each time and each method, the same error occurs.
Thanks in advance,
Rich
UPDATE
I re-recorded the macro and simply changed the order of what I did during the record. I no longer get the error. However the code is very messy and long winded. The screen flickers a lot during the process too. is there a way to make it a smoother experience for the user? The new code is below
Sub MergeAll2()
'
' MergeAll2 Macro
'
'
' Open All
Workbooks.Open Filename:= _
"S:\UFD\24 Reports\02 Time Keeping\PT Time Sheets\2016_7.xlsx"
Workbooks.Open Filename:= _
"S:\UFD\24 Reports\02 Time Keeping\PT Time Sheets\2016_8.xlsx"
Workbooks.Open Filename:= _
"S:\UFD\24 Reports\02 Time Keeping\PT Time Sheets\2016_9.xlsx"
Workbooks.Open Filename:= _
"S:\UFD\24 Reports\02 Time Keeping\PT Time Sheets\2016_JAMAL.xlsx"
Workbooks.Open Filename:= _
"S:\UFD\24 Reports\02 Time Keeping\PT Time Sheets\2016_LOKESH.xlsx"
Workbooks.Open Filename:= _
"S:\UFD\24 Reports\02 Time Keeping\PT Time Sheets\2016_NONI.xlsx"
Workbooks.Open Filename:= _
"S:\UFD\24 Reports\02 Time Keeping\PT Time Sheets\2016_RAJESH.xlsx"
Workbooks.Open Filename:= _
"S:\UFD\24 Reports\02 Time Keeping\PT Time Sheets\2016_SANTHOSH.xlsx"
Workbooks.Open Filename:= _
"S:\UFD\24 Reports\02 Time Keeping\PT Time Sheets\2016_WARREN.xlsx"
' Copy & Paste
Windows("2016_JAMAL.xlsx").Activate
Range("G2:J2").Select
Selection.Copy
Windows("master.xlsm").Activate
Range("C2").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Windows("2016_LOKESH.xlsx").Activate
Range("G2:J2").Select
Application.CutCopyMode = False
Selection.Copy
Windows("master.xlsm").Activate
Range("C3:F3").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Windows("2016_NONI.xlsx").Activate
Range("G2:J2").Select
Application.CutCopyMode = False
Selection.Copy
Windows("master.xlsm").Activate
Range("C4").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Windows("2016_RAJESH.xlsx").Activate
Range("G2:J2").Select
Application.CutCopyMode = False
Selection.Copy
Windows("master.xlsm").Activate
Range("C5").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Windows("2016_SANTHOSH.xlsx").Activate
Range("G2:J2").Select
Application.CutCopyMode = False
Selection.Copy
Windows("master.xlsm").Activate
Range("C6").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Windows("2016_WARREN.xlsx").Activate
Range("G2:J2").Select
Application.CutCopyMode = False
Selection.Copy
Windows("master.xlsm").Activate
Range("C7").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Windows("2016_7.xlsx").Activate
Range("G2:J2").Select
Application.CutCopyMode = False
Selection.Copy
Windows("master.xlsm").Activate
Range("C8").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Windows("2016_8.xlsx").Activate
Range("G2:J2").Select
Application.CutCopyMode = False
Selection.Copy
Windows("master.xlsm").Activate
Range("C9").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Windows("2016_9.xlsx").Activate
Range("G2:J2").Select
Application.CutCopyMode = False
Selection.Copy
Windows("master.xlsm").Activate
Range("C10").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
' Close All
Windows("2016_JAMAL.xlsx").Activate
ActiveWindow.Close
Windows("2016_LOKESH.xlsx").Activate
ActiveWindow.Close
Windows("2016_NONI.xlsx").Activate
ActiveWindow.Close
Windows("2016_RAJESH.xlsx").Activate
ActiveWindow.Close
Windows("2016_SANTHOSH.xlsx").Activate
ActiveWindow.Close
Windows("2016_WARREN.xlsx").Activate
ActiveWindow.Close
Windows("2016_7.xlsx").Activate
ActiveWindow.Close
Windows("2016_8.xlsx").Activate
ActiveWindow.Close
Windows("2016_9.xlsx").Activate
ActiveWindow.Close
End Sub
UPDATE 2
Many thanks for the help so far. I am looking to edit this line:
Workbooks("master").ActiveSheet.Range("C2:F2").Value = Workbooks("2016_JAMAL").ActiveSheet.Range("G2:J2").Value
So that I can choose which sheet in "master" to write it to and also which sheet in "2016_JAMAL" to copy it from.
Secondly, I want to copy from two ranges on this sheet - C2:G2 and C5:G56
I would like to do this in a streamlined way.
Many thanks for your answers so far - I will read the information on Arrays and work through the 5 pages!
Rich
You can stop the flickering screen by setting the following:
Application.ScreenUpdating = False
Add that to your macro and run it again.
You should be able to speed up your "Copy & Paste" section by using this instead:
With Workbooks("master").ActiveSheet
.Range("C2:F2").Value = Workbooks("2016_JAMAL").ActiveSheet.Range("G2:J2").Value
.Range("C3:F3").Value = Workbooks("2016_LOKESH").ActiveSheet.Range("G2:J2").Value
.Range("C4:F4").Value = Workbooks("2016_NONI").ActiveSheet.Range("G2:J2").Value
.Range("C5:F5").Value = Workbooks("2016_RAJESH").ActiveSheet.Range("G2:J2").Value
.Range("C6:F6").Value = Workbooks("2016_SANTHOSH").ActiveSheet.Range("G2:J2").Value
.Range("C7:F7").Value = Workbooks("2016_WARREN").ActiveSheet.Range("G2:J2").Value
.Range("C8:F8").Value = Workbooks("2016_7").ActiveSheet.Range("G2:J2").Value
.Range("C9:F9").Value = Workbooks("2016_8").ActiveSheet.Range("G2:J2").Value
.Range("C10:F10").Value = Workbooks("2016_9").ActiveSheet.Range("G2:J2").Value
End With
You could also make your "close" part simpler by using:
Workbooks("2016_JAMAL.xlsx").Close False
Workbooks("2016_LOKESH.xlsx").Close False
Workbooks("2016_NONI.xlsx").Close False
Workbooks("2016_RAJESH.xlsx").Close False
Workbooks("2016_SANTHOSH.xlsx").Close False
Workbooks("2016_WARREN.xlsx").Close False
Workbooks("2016_7.xlsx").Close False
Workbooks("2016_8.xlsx").Close False
Workbooks("2016_9.xlsx").Close False
I used Activesheet not knowing how many sheets each workbook has or their names. You can adjust accordingly. Here's my version:
Option Explicit
Sub MergeAll2()
Dim wb2016_7 As Workbook
Dim wb2016_8 As Workbook
Dim wb2016_9 As Workbook
Dim wb2016_JAMAL As Workbook
Dim wb2016_LOKESH As Workbook
Dim wb2016_NONI As Workbook
Dim wb2016_RAJESH As Workbook
Dim wb2016_SANTHOSH As Workbook
Dim wb2016_WARREN As Workbook
Dim strPath As String
Application.ScreenUpdating = False
strPath = "S:\UFD\24 Reports\02 Time Keeping\PT Time Sheets\"
Set wb2016_7 = Workbooks.Open(Filename:=strPath & "2016_7.xlsx")
Set wb2016_8 = Workbooks.Open(Filename:=strPath & "2016_8.xlsx")
Set wb2016_9 = Workbooks.Open(Filename:=strPath & "2016_9.xlsx")
Set wb2016_JAMAL = Workbooks.Open(Filename:=strPath & "2016_JAMAL.xlsx")
Set wb2016_LOKESH = Workbooks.Open(Filename:=strPath & "2016_LOKESH.xlsx")
Set wb2016_NONI = Workbooks.Open(Filename:=strPath & "2016_NONI.xlsx")
Set wb2016_RAJESH = Workbooks.Open(Filename:=strPath & "2016_RAJESH.xlsx")
Set wb2016_SANTHOSH = Workbooks.Open(Filename:=strPath & "2016_SANTHOSH.xlsx")
Set wb2016_WARREN = Workbooks.Open(Filename:=strPath & "2016_WARREN.xlsx")
With Workbooks("master").ActiveSheet
.Range("C2:F2").Value = wb2016_JAMAL.ActiveSheet.Range("G2:J2").Value
.Range("C3:F3").Value = wb2016_LOKESH.ActiveSheet.Range("G2:J2").Value
.Range("C4:F4").Value = wb2016_NONI.ActiveSheet.Range("G2:J2").Value
.Range("C5:F5").Value = wb2016_RAJESH.ActiveSheet.Range("G2:J2").Value
.Range("C6:F6").Value = wb2016_SANTHOSH.ActiveSheet.Range("G2:J2").Value
.Range("C7:F7").Value = wb2016_WARREN.ActiveSheet.Range("G2:J2").Value
.Range("C8:F8").Value = wb2016_7.ActiveSheet.Range("G2:J2").Value
.Range("C9:F9").Value = wb2016_8.ActiveSheet.Range("G2:J2").Value
.Range("C10:F10").Value = wb2016_9.ActiveSheet.Range("G2:J2").Value
End With
wb2016_7.Close True
wb2016_8.Close True
wb2016_9.Close True
wb2016_JAMAL.Close True
wb2016_LOKESH.Close True
wb2016_NONI.Close True
wb2016_RAJESH.Close True
wb2016_SANTHOSH.Close True
wb2016_WARREN.Close True
Set wb2016_7 = Nothing
Set wb2016_8 = Nothing
Set wb2016_9 = Nothing
Set wb2016_JAMAL = Nothing
Set wb2016_LOKESH = Nothing
Set wb2016_NONI = Nothing
Set wb2016_RAJESH = Nothing
Set wb2016_SANTHOSH = Nothing
Set wb2016_WARREN = Nothing
Application.ScreenUpdating = True
End Sub
It's good practice to use Option Explicit which forces you to declare your variables and to set your objects back to Nothing after using them.
EDIT
I would replace Activesheet with Sheets("SheetName") for each of the workbooks. Otherwise you could put the following code in the workbook object for every workbook (and save them all as macro enabled), except master, and keep Activesheet:
Private Sub Workbook_Open( )
Sheets ("SheetName").Activate
End Sub
I would, at least, change Workbooks("master").ActiveSheet to Workbooks("master").Sheets("SheetName") or you'll need to remember to run it from the correct (that is, active) sheet. This is a very helpful link, also.
This will merge a range from all workbooks in a folder (next data set goes below prior).
Sub Basic_Example_1()
Dim MyPath As String, FilesInPath As String
Dim MyFiles() As String
Dim SourceRcount As Long, Fnum As Long
Dim mybook As Workbook, BaseWks As Worksheet
Dim sourceRange As Range, destrange As Range
Dim rnum As Long, CalcMode As Long
'Fill in the path\folder where the files are
MyPath = "C:\Users\Ron\test"
'Add a slash at the end if the user forget it
If Right(MyPath, 1) <> "\" Then
MyPath = MyPath & "\"
End If
'If there are no Excel files in the folder exit the sub
FilesInPath = Dir(MyPath & "*.xl*")
If FilesInPath = "" Then
MsgBox "No files found"
Exit Sub
End If
'Fill the array(myFiles)with the list of Excel files in the folder
Fnum = 0
Do While FilesInPath <> ""
Fnum = Fnum + 1
ReDim Preserve MyFiles(1 To Fnum)
MyFiles(Fnum) = FilesInPath
FilesInPath = Dir()
Loop
'Change ScreenUpdating, Calculation and EnableEvents
With Application
CalcMode = .Calculation
.Calculation = xlCalculationManual
.ScreenUpdating = False
.EnableEvents = False
End With
'Add a new workbook with one sheet
Set BaseWks = Workbooks.Add(xlWBATWorksheet).Worksheets(1)
rnum = 1
'Loop through all files in the array(myFiles)
If Fnum > 0 Then
For Fnum = LBound(MyFiles) To UBound(MyFiles)
Set mybook = Nothing
On Error Resume Next
Set mybook = Workbooks.Open(MyPath & MyFiles(Fnum))
On Error GoTo 0
If Not mybook Is Nothing Then
On Error Resume Next
With mybook.Worksheets(1)
Set sourceRange = .Range("A1:C1")
End With
If Err.Number > 0 Then
Err.Clear
Set sourceRange = Nothing
Else
'if SourceRange use all columns then skip this file
If sourceRange.Columns.Count >= BaseWks.Columns.Count Then
Set sourceRange = Nothing
End If
End If
On Error GoTo 0
If Not sourceRange Is Nothing Then
SourceRcount = sourceRange.Rows.Count
If rnum + SourceRcount >= BaseWks.Rows.Count Then
MsgBox "Sorry there are not enough rows in the sheet"
BaseWks.Columns.AutoFit
mybook.Close savechanges:=False
GoTo ExitTheSub
Else
'Copy the file name in column A
With sourceRange
BaseWks.cells(rnum, "A"). _
Resize(.Rows.Count).Value = MyFiles(Fnum)
End With
'Set the destrange
Set destrange = BaseWks.Range("B" & rnum)
'we copy the values from the sourceRange to the destrange
With sourceRange
Set destrange = destrange. _
Resize(.Rows.Count, .Columns.Count)
End With
destrange.Value = sourceRange.Value
rnum = rnum + SourceRcount
End If
End If
mybook.Close savechanges:=False
End If
Next Fnum
BaseWks.Columns.AutoFit
End If
ExitTheSub:
'Restore ScreenUpdating, Calculation and EnableEvents
With Application
.ScreenUpdating = True
.EnableEvents = True
.Calculation = CalcMode
End With
End Sub
This will merge a range from all workbooks in a folder (next data set goes to the right of prior).
Sub Basic_Example_3()
Dim MyPath As String, FilesInPath As String
Dim MyFiles() As String
Dim SourceCcount As Long, Fnum As Long
Dim mybook As Workbook, BaseWks As Worksheet
Dim sourceRange As Range, destrange As Range
Dim Cnum As Long, CalcMode As Long
'Fill in the path\folder where the files are
MyPath = "C:\Users\Ron\test"
'Add a slash at the end if the user forget it
If Right(MyPath, 1) <> "\" Then
MyPath = MyPath & "\"
End If
'If there are no Excel files in the folder exit the sub
FilesInPath = Dir(MyPath & "*.xl*")
If FilesInPath = "" Then
MsgBox "No files found"
Exit Sub
End If
'Fill the array(myFiles)with the list of Excel files in the folder
Fnum = 0
Do While FilesInPath <> ""
Fnum = Fnum + 1
ReDim Preserve MyFiles(1 To Fnum)
MyFiles(Fnum) = FilesInPath
FilesInPath = Dir()
Loop
'Change ScreenUpdating, Calculation and EnableEvents
With Application
CalcMode = .Calculation
.Calculation = xlCalculationManual
.ScreenUpdating = False
.EnableEvents = False
End With
'Add a new workbook with one sheet
Set BaseWks = Workbooks.Add(xlWBATWorksheet).Worksheets(1)
Cnum = 1
'Loop through all files in the array(myFiles)
If Fnum > 0 Then
For Fnum = LBound(MyFiles) To UBound(MyFiles)
Set mybook = Nothing
On Error Resume Next
Set mybook = Workbooks.Open(MyPath & MyFiles(Fnum))
On Error GoTo 0
If Not mybook Is Nothing Then
On Error Resume Next
Set sourceRange = mybook.Worksheets(1).Range("A1:A10")
If Err.Number > 0 Then
Err.Clear
Set sourceRange = Nothing
Else
'if SourceRange use all rows then skip this file
If sourceRange.Rows.Count >= BaseWks.Rows.Count Then
Set sourceRange = Nothing
End If
End If
On Error GoTo 0
If Not sourceRange Is Nothing Then
SourceCcount = sourceRange.Columns.Count
If Cnum + SourceCcount >= BaseWks.Columns.Count Then
MsgBox "Sorry there are not enough columns in the sheet"
BaseWks.Columns.AutoFit
mybook.Close savechanges:=False
GoTo ExitTheSub
Else
'Copy the file name in the first row
With sourceRange
BaseWks.cells(1, Cnum). _
Resize(, .Columns.Count).Value = MyFiles(Fnum)
End With
'Set the destrange
Set destrange = BaseWks.cells(2, Cnum)
'we copy the values from the sourceRange to the destrange
With sourceRange
Set destrange = destrange. _
Resize(.Rows.Count, .Columns.Count)
End With
destrange.Value = sourceRange.Value
Cnum = Cnum + SourceCcount
End If
End If
mybook.Close savechanges:=False
End If
Next Fnum
BaseWks.Columns.AutoFit
End If
ExitTheSub:
'Restore ScreenUpdating, Calculation and EnableEvents
With Application
.ScreenUpdating = True
.EnableEvents = True
.Calculation = CalcMode
End With
End Sub
Related
I've created a macro to get data from active workbook, copy it into a new one and save new file. Whole code worked perfect until I changed Office to 365 with Onedrive on my computer.
When I run this macro, I get error 1004: Premission denied in macro below
Sub create_new()
Dim SheetI As Worksheet
Dim SheetO As Worksheet
Dim BookO As Workbook
Dim BookI As Workbook
Dim row As Long
Dim i As Long
Dim dict As Object
Dim path As String
Dim brng As Range
Dim found As Boolean
path = CreateObject("WScript.Shell").SpecialFolders("MyDocuments") & "\path\"
If Len(Dir(path, vbDirectory)) = 0 Then MkDir path
path = path & _
Format(Date, "ddmmmyyyy") & ".xlsx"
If Dir(path) <> "" Then Kill path
Set BookI = ThisWorkbook
Set BookO = Workbooks.Add
With BookO
BookO.Sheets.Add.Name = "Name"
Set SheetO = BookO.Sheets("Name")
SheetO.Cells(1, 1).Value = "1"
SheetO.Cells(1, 2).Value = "2"
SheetO.Cells(1, 3).Value = "3"
SheetO.Columns("A:H").AutoFit
SheetO.Range("a1:h1").Font.Bold = True
Application.DisplayAlerts = False
.SaveAs path
Application.DisplayAlerts = True
End With
Set dict = SubTotals(BookI)
For Each SheetI In BookI.Sheets
If SheetI.Name <> "Dane" Then
For row = 10 To SheetI.Cells(Rows.Count, 1).End(xlUp).row Step 1
If i <= row Then
If SheetI.Cells(row, 2).Value = "Oprysk" Then
If Not found Then found = True
i = row
If SheetI.Cells(row, 2).MergeCells Then i = row + SheetI.Cells(row, 2).MergeArea.Rows.Count - 1
With BookO
Range(SheetI.Cells(row, 1), SheetI.Cells(i, 1)).Copy
SheetO.Cells(Rows.Count, 1).End(xlUp).Offset(1, 0).PasteSpecial Paste:=xlPasteValuesAndNumberFormats, Operation:=xlNone, _
SkipBlanks:=False, Transpose:=False
Range(SheetI.Cells(row, 5), SheetI.Cells(i, 8)).Copy
SheetO.Cells(Rows.Count, 5).End(xlUp).Offset(1, 0).PasteSpecial Paste:=xlPasteValuesAndNumberFormats, Operation:=xlNone, _
SkipBlanks:=False, Transpose:=False
SheetI.Cells(2, 2).Copy
SheetO.Cells(Rows.Count, 2).End(xlUp).Offset(1, 0).PasteSpecial Paste:=xlPasteValuesAndNumberFormats, Operation:=xlNone, _
SkipBlanks:=False, Transpose:=False
SheetI.Cells(3, 5).Copy
SheetO.Cells(Rows.Count, 3).End(xlUp).Offset(1, 0).PasteSpecial Paste:=xlPasteValuesAndNumberFormats, Operation:=xlNone, _
SkipBlanks:=False, Transpose:=False
SheetO.Cells(Rows.Count, 4).End(xlUp).Offset(1, 0).Value = SearchDict(dict, SheetO.Cells(Rows.Count, 3).End(xlUp).Value)
If i <> row Then
For l = 1 To 8 Step 1
If l <> 6 And l <> 7 Then
Application.DisplayAlerts = False
Range(SheetO.Cells(Rows.Count, l).End(xlUp), SheetO.Cells(Rows.Count, l).End(xlUp).Offset(i - row, 0)).Merge
Application.DisplayAlerts = True
End If
Next l
End If
End With
End If
End If
Next row
End If
Next SheetI
If found Then
Set brng = Range(SheetO.Cells(1, 1), SheetO.Cells(Rows.Count, 6).End(xlUp).Offset(0, 2))
With BookO
brng.BorderAround xlContinuous, xlThin
brng.Borders(xlInsideHorizontal).LineStyle = xlContinuous
brng.Borders(xlInsideVertical).LineStyle = xlContinuous
Application.DisplayAlerts = False
.SaveAs path
Application.DisplayAlerts = True
End With
MsgBox "File saved in path: " & path
Else
With BookO
Application.DisplayAlerts = False
BookO.Close
Application.DisplayAlerts = True
End With
Kill path
MsgBox "Data not found"
End If
End Sub
So basicly I check here if the path and file exists. If not, its created. I save the new workbook for the first time when its formated but before data is copied. Secondly its saved when the data is copied and this second attempt to save workbook fails with error above. Why I was able to overwrite this workbook when I didnt use Onedrive and now, when I do it shows me the error?
Im trying to Extract data from multiple Ranges in multiple Excel files, then transpose the copied data preserving the Link option. So under : Selection.PasteSpecial Paste:=xlPasteAll, Transpose:=True I added the following code : ActiveSheet.Paste Link:=True
But using this code the macro doesn't correctly link the data. Thank you !
This is the code Im using :
Sub ImportData()
Dim FileNames As Variant
Dim i As Integer
Dim j As Integer
'Application.ScreenUpdating = False
Range("C2").Select
FileNames = Application.GetOpenFilename(FileFilter:="Excel Filter (*.xlsx), *.xlsx", Title:="Open File(s)", MultiSelect:=True)
For i = 1 To UBound(FileNames)
Workbooks.Open FileNames(i)
Sheets("Global").Activate
Range("D45:O45").Select
Selection.Copy
Windows("Dashboard.xlsm").Activate
Selection.PasteSpecial Paste:=xlPasteAll, Transpose:=True
ActiveSheet.Paste Link:=True
Workbooks.Open FileNames(i)
ActiveWorkbook.Close savechanges:=False
ActiveCell.Offset(0, 1).Activate
'D45:O45 Line
Workbooks.Open FileNames(i)
Sheets("Global").Activate
Range("D8:O8").Select
Selection.Copy
Windows("Dashboard.xlsm").Activate
Selection.PasteSpecial Paste:=xlPasteAll, Transpose:=True
ActiveSheet.Paste Link:=True
Workbooks.Open FileNames(i)
ActiveWorkbook.Close savechanges:=False
ActiveCell.Offset(0, 1).Activate
'D8:O8 Line
Workbooks.Open FileNames(i)
Sheets("Global").Activate
Range("D24:O24").Select
Selection.Copy
Windows("Dashboard.xlsm").Activate
Selection.PasteSpecial Paste:=xlPasteAll, Transpose:=True
ActiveSheet.Paste Link:=True
Workbooks.Open FileNames(i)
ActiveWorkbook.Close savechanges:=False
ActiveCell.Offset(0, 1).Activate
'D24:O24 Line
Workbooks.Open FileNames(i)
Sheets("Global").Activate
Range("D33:O33").Select
Selection.Copy
Windows("Dashboard.xlsm").Activate
Selection.PasteSpecial Paste:=xlPasteAll, Transpose:=True
ActiveSheet.Paste Link:=True
Workbooks.Open FileNames(i)
ActiveWorkbook.Close savechanges:=False
ActiveCell.Offset(0, 1).Activate
'D33:O33 Line
Workbooks.Open FileNames(i)
Sheets("Global").Activate
Range("D5:O5").Select
Selection.Copy
Windows("Dashboard.xlsm").Activate
Selection.PasteSpecial Paste:=xlPasteAll, Transpose:=True
ActiveSheet.Paste Link:=True
Workbooks.Open FileNames(i)
ActiveWorkbook.Close savechanges:=False
ActiveCell.Offset(0, 1).Activate
'D5:O5 Line
Workbooks.Open FileNames(i)
Sheets("Global").Activate
Range("D38:O38").Select
Selection.Copy
Windows("Dashboard.xlsm").Activate
Selection.PasteSpecial Paste:=xlPasteAll, Transpose:=True
ActiveSheet.Paste Link:=True
Workbooks.Open FileNames(i)
ActiveWorkbook.Close savechanges:=False
ActiveCell.Offset(0, 1).Activate
'D38:O38 Line
Workbooks.Open FileNames(i)
Sheets("Global").Activate
Range("D108:O108").Select
Selection.Copy
Windows("Dashboard.xlsm").Activate
Selection.PasteSpecial Paste:=xlPasteAll, Transpose:=True
ActiveSheet.Paste Link:=True
Workbooks.Open FileNames(i)
ActiveWorkbook.Close savechanges:=False
ActiveCell.Offset(0, 1).Activate
'D108:O108 Line
Workbooks.Open FileNames(i)
Sheets("Global").Activate
Range("D10: O10 ").Select
Selection.Copy
Windows("Dashboard.xlsm").Activate
Selection.PasteSpecial Paste:=xlPasteAll, Transpose:=True
ActiveSheet.Paste Link:=True
Workbooks.Open FileNames(i)
ActiveWorkbook.Close savechanges:=False
ActiveCell.Offset(0, 1).Activate
'D10:O10 Line
Workbooks.Open FileNames(i)
Sheets("Global").Activate
Range("D131:O131").Select
Selection.Copy
Windows("Dashboard.xlsm").Activate
Selection.PasteSpecial Paste:=xlPasteAll, Transpose:=True
ActiveSheet.Paste Link:=True
Workbooks.Open FileNames(i)
ActiveWorkbook.Close savechanges:=False
ActiveCell.Offset(12, -8).Activate
'D131:O131 Line
Next i
End Sub
Paste Link Workaround
Paste Link does not work with Transpose.
Assuming that the code is in the destination workbook and that the results will be written to its ActiveSheet (rather qualify with its name e.g. "Sheet1"), you can use the followng.
The Code
Option Explicit
Sub ImportData()
' Destination
Const dstFirst As String = "C2"
' Source
Const Cols As String = "D:O"
Dim RowNumbers As Variant
RowNumbers = VBA.Array(45, 8, 24, 33, 5, 38, 108, 10, 131)
' Destination
Dim wb As Workbook
Set wb = ThisWorkbook ' The workbook containing this code.
Dim ws As Worksheet
Set ws = wb.ActiveSheet ' Better define: Set ws = wb.worksheets("Sheet1")
Dim dstInit As Range
Set dstInit = ws.Range(dstFirst)
' Source
Dim DataCount As Long
DataCount = ws.Columns(Cols).Count
Dim LB As Long
LB = LBound(RowNumbers)
Dim UB As Long
UB = UBound(RowNumbers)
Dim FileNames As Variant
FileNames = Application.GetOpenFilename( _
FileFilter:="Excel Filter (*.xlsx), *.xlsx", _
Title:="Open File(s)", _
MultiSelect:=True)
Application.ScreenUpdating = False
' Prepare for loop.
Dim src As Range ' Current Source Range
Dim dst As Range ' Current Destination Range
Dim i As Long ' File Names Counter
Dim j As Long ' Destination Rows and Source Columns Counter
Dim n As Long ' Source Rows and Destination Columns Counter
Dim CurForm As String ' Current Left Part of Formula
' Write values from Source to Destination.
For i = 1 To UBound(FileNames)
With Workbooks.Open(FileNames(i)).Worksheets("Global")
CurForm = "='[" & .Parent.Name & "]" & .Name & "'!"
Set dst = dstInit.Offset((i - 1) * DataCount)
For n = LB To UB
Set src = .Columns(Cols).Rows(RowNumbers(n))
For j = 1 To DataCount
dst.Offset(j - 1, n).Formula _
= CurForm & src.Cells(j).Address(0, 0)
Next j
Next n
.Parent.Close SaveChanges:=False
End With
Next i
Application.ScreenUpdating = True
' Inform user.
MsgBox "Data transferred.", vbInformation, "Success"
End Sub
Just wondering if anyone can help me clean up my code. It currently works perfectly for what I need it to do. Just wondering if it can run faster. Right now it seems to open and close each workbook 3 times before moving to the next one.
Sub JanuaryMacro()
Dim strF As String, strP As String
Dim wb As Workbook
Range("B2:M2").clearcontents
'Edit this declaration to your folder name
strP = "\\My path" 'change for the path of your folder
strF = Dir(strP & "\*.xlsx")
Application.DisplayAlerts = False
Application.AskToUpdateLinks = False
Do While strF <> vbNullString
Set wb = Workbooks.Open(strP & "\" & strF)
Range("Totals").Select
Selection.Copy
Windows("Monthly Report.xlsm").Activate
Range("D2:M2").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlAdd, SkipBlanks _
:=False, Transpose:=False
Set wb = Workbooks.Open(strP & "\" & strF)
Range("FG_Approvals").Select
Selection.Copy
Windows("Monthly Report.xlsm").Activate
Range("C2").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlAdd, SkipBlanks _
:=False, Transpose:=False
Set wb = Workbooks.Open(strP & "\" & strF)
Range("Allocations").Select
Selection.Copy
Windows("Monthly Report.xlsm").Activate
Range("B2").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlAdd, SkipBlanks _
:=False, Transpose:=False
wb.Close SaveChanges:=False
strF = Dir()
Loop
Application.DisplayAlerts = True
End Sub
You should use references to your monthly-report-sheet, the new workbook and its sheet e. g. like this:
Sub JanuaryMacroVersion2()
Dim strF As String, strP As String
Dim mr As Worksheet
Dim wb As Workbook, ws As Worksheet
Set mr = ActiveSheet ' your monthly report
mr.Range("B2:M2").ClearContents
strP = "\\My path" 'change for the path of your folder
strF = Dir(strP & "\*.xlsx")
Application.DisplayAlerts = False
Application.AskToUpdateLinks = False
Do While strF <> vbNullString
Set wb = Workbooks.Open(strP & "\" & strF)
Set ws = ActiveSheet
ws.Range("Totals").Copy
mr.Range("D2:M2").PasteSpecial _
Paste:=xlPasteValues, Operation:=xlAdd, _
SkipBlanks:=False, Transpose:=False
ws.Range("FG_Approvals").Copy
mr.Range("C2").PasteSpecial _
Paste:=xlPasteValues, Operation:=xlAdd, _
SkipBlanks:=False, Transpose:=False
ws.Range("Allocations").Copy
mr.Range("B2").PasteSpecial _
Paste:=xlPasteValues, Operation:=xlAdd, _
SkipBlanks:=False, Transpose:=False
wb.Close SaveChanges:=False
strF = Dir()
Loop
Application.DisplayAlerts = True
End Sub
If the range names like "FG_Approvals" refer to a workbook wide name, replace ws.Range("FG_Approvals")by wb.Range("FG_Approvals").
Next optimization step would be omitting copy/paste by assigning their Range.Value directly:
Sub JanuaryMacroVersion3()
Dim strF As String, strP As String
Dim mr As Worksheet
Dim wb As Workbook, ws As Worksheet
Dim lastRow As Long
Set mr = ActiveSheet
mr.Range("B2:M2").ClearContents
strP = "\\My path" 'change for the path of your folder
strF = Dir(strP & "\*.xlsx")
Application.DisplayAlerts = False
Application.AskToUpdateLinks = False
Do While strF <> vbNullString
Set wb = Workbooks.Open(strP & "\" & strF)
Set ws = ActiveSheet
lastRow = mr.Cells(mr.Rows.Count, "D").End(xlUp).Row
mr.Cells(lastRow + 1, "D").Resize _
(ws.Range("Totals").Rows.Count, _
ws.Range("Totals").Columns.Count).Value _
= ws.Range("Totals").Value
lastRow = mr.Cells(mr.Rows.Count, "C").End(xlUp).Row
mr.Cells(lastRow + 1, "C").Resize _
(ws.Range("FG_Approvals").Rows.Count, _
ws.Range("FG_Approvals").Columns.Count).Value _
= ws.Range("FG_Approvals").Value
lastRow = mr.Cells(mr.Rows.Count, "B").End(xlUp).Row
mr.Cells(lastRow + 1, "B").Resize _
(ws.Range("Allocations").Rows.Count, _
ws.Range("Allocations").Columns.Count).Value _
= ws.Range("Allocations").Value
wb.Close SaveChanges:=False
strF = Dir()
Loop
Application.DisplayAlerts = True
End Sub
I am aiming to split out all the worksheets of my workbook, save them as individual files and then, to each new workbook, add a Guidance worksheet (guidance worksheet is the same for all workbooks). The part of the code works perfectly, filling empty xPath directory with a new workbook for each tab.
The code then completely skips the Do While loop section for no reason. If you comment out the For Each loop, then it works. I have no idea why.
Sub SplitWorkbooktoFile()
Dim xPath As String
Dim wb As Workbook
Dim file As String
Set wb = ActiveWorkbook
xPath = "C:\Users\AH Test\"
file = Dir(xPath)
Application.ScreenUpdating = False
Application.DisplayAlerts = False
For Each xWs In wb.Sheets
xWs.Copy
Application.ActiveWorkbook.SaveAs Filename:=xPath & "\" & xWs.Name & ".xlsx"
Application.ActiveWorkbook.Close False
Next
Do While Not file = ""
Workbooks.Open (xPath & file)
Set wb = ActiveWorkbook
Sheets.Add after:=Sheets(Sheets.Count)
ActiveSheet.Name = "User Guidance"
ThisWorkbook.Sheets("Guidance").Range("A1:C8").Copy
wb.Sheets("User Guidance").Range("A1").PasteSpecial Paste:=xlPasteColumnWidths, Operation:=xlNone, SkipBlanks:=False, Transpose:=False
wb.Sheets("User Guidance").Range("A1").PasteSpecial Paste:=xlPasteFormats, Operation:=xlNone, SkipBlanks:=False, Transpose:=False
wb.Sheets("User Guidance").Range("A1").PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks:=False, Transpose:=False
wb.Save
wb.Close
file = Dir
Loop
Application.DisplayAlerts = True
Application.ScreenUpdating = True
End Sub
Thank you to #Nathan_Sav for prompting me to the correct answer. Just needed to put the file = dir(xpath) after the for each loop.
Sub SplitWorkbooktoFile()
Dim xPath As String
Dim wb As Workbook
Dim file As String
Set wb = ActiveWorkbook
xPath = "C:\Users\AH Test\"
Application.ScreenUpdating = False
Application.DisplayAlerts = False
For Each xWs In wb.Sheets
xWs.Copy
Application.ActiveWorkbook.SaveAs Filename:=xPath & "\" & xWs.Name & ".xlsx"
Application.ActiveWorkbook.Close False
Next
file = Dir(xPath)
Do While Not file = ""
Workbooks.Open (xPath & file)
Set wb = ActiveWorkbook
Sheets.Add after:=Sheets(Sheets.Count)
ActiveSheet.Name = "User Guidance"
ThisWorkbook.Sheets("Guidance").Range("A1:C8").Copy
wb.Sheets("User Guidance").Range("A1").PasteSpecial Paste:=xlPasteColumnWidths, Operation:=xlNone, SkipBlanks:=False, Transpose:=False
wb.Sheets("User Guidance").Range("A1").PasteSpecial Paste:=xlPasteFormats, Operation:=xlNone, SkipBlanks:=False, Transpose:=False
wb.Sheets("User Guidance").Range("A1").PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks:=False, Transpose:=False
wb.Save
wb.Close
file = Dir
Loop
Application.DisplayAlerts = True
Application.ScreenUpdating = True
End Sub
I have a workbook which performs several Excel-functions that depend on one variable and fills out itself. I have a loop to create those forms and save in a directory but before that I want to copy all and paste special so that formulas will be gone.
Sub SaveAs1()
For i = 172 To 225
Dim SaveName As Integer
SaveName = ActiveWorkbook.Sheets(1).Range("bi1").value
Application.ActiveWorkbook.SaveAs "C:\" & SaveName
Range("bi1") = i + 1
Next
End Sub
I figure that out finally using trial and error method
Sub Save()
Rem kaydetmece dongusu
For i = 172 To 180 Step 1
Application.DisplayAlerts = False
Workbooks.Open Filename:="C:\"
Range("bi1") = i + 1
Dim SaveName As Integer
SaveName = ActiveWorkbook.Sheets(1).Range("bi1").value
Range("A1:BE63").Select
Range("a1").Activate
Selection.Copy
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Application.CutCopyMode = False
Application.ActiveWorkbook.SaveAs "C:\" & SaveName
Columns("BE:BU").Select
Selection.Delete Shift:=xlToLeft
Sheets("CAL").Select
ActiveWindow.SelectedSheets.Delete
Sheets("sahadan").Select
ActiveWindow.SelectedSheets.Delete
ActiveWorkbook.Close True
Next
End Sub
If you're asking how to paste values, this is how you do it. Replace "A1" with the actual range you need to use.
Range("A1").Copy
Range("A1").PasteSpecial xlPasteValues