How to run VBA in excel, when Excel filename got changed - vba

I have a Workbook (1) contains 2 sheets. In my program, I would like to generate a workbook (2) which Create 2 sheets. Then the program will filter the table and copy values from workbook 1 to workbook 2.
But my problem is my workbook (1) name will get changed every time. I tried to use ActiveWorkbook.Name. But when the program is running, it will create a new workbook then suddenly it became an active workbook.
I named my main Workbook (1) as Filevalue. But not working. How to solve this problem. I need to run this program eventhough when the name get changed. Help me
Sub createlandDE()
Filepath = ActiveWorkbook.path
FileValue = ActiveWorkbook.Name 'Problem With Activeworkbook
NameValue = Format(Date, "yymmdd") & "-DE"
Dim wb As Workbook
Set wb = Workbooks.add
Dim path As String
Dim FSO As Object
path = Filepath & "\" & NameValue & ".xlsx"
Set FSO = CreateObject("Scripting.FileSystemObject")
If FSO.FileExists(path) Then
On Error Resume Next
Workbooks(NameValue & ".xlsx").Close False
Kill path
wb.SaveAs path
Sheets(3).Delete
Else
wb.SaveAs path
Sheets(3).Delete
End If
Application.ScreenUpdating = False
Dim ws, ws1, ws2 As Worksheet
Dim table1, table2 As ListObject
Dim rng1 As Range
Sheets(1).Name = "Main view"
Sheets(2).Name = "Overall view"
Set ws1 = Workbooks(NameValue & ".xlsx").Worksheets("Main view")
ws1.ListObjects.add(xlSrcRange, ws1.Range("A$1:$J$1"), , xlYes).Name = "MainTable"
Set table1 = ws1.ListObjects(1)
Set ws = Workbooks(FileValue).Worksheets("Main") 'Problem With Activeworkbook
ws.PivotTables("MainTable").PivotFields("Dealer Country Code").CurrentPage = "DE"
With ws
LastRow = .Range("A" & .Rows.Count).End(xlUp).Row
Set rng1 = Range(.Range("A4"), .Range("J" & LastRow))
End With
rng1.Copy
ws1.Range("A1").PasteSpecial Paste:=xlPasteAllUsingSourceTheme, Operation:=xlNone, SkipBlanks:=False, Transpose:=False
Set ws2 = Sheets("Overall view")
ws2.ListObjects.add(xlSrcRange, ws2.Range("A$1:$Q$1"), , xlYes).Name = "OverallTable"
Set table2 = ws2.ListObjects(1)
Worksheets("Overall view").ListObjects("OverallTable").TableStyle = "Table Style 1"
Workbooks(FileValue).Activate 'Problem With Activeworkbook
Sheet2.ListObjects("DataTable").Range.AutoFilter Field:=1
Sheet2.ListObjects("DataTable").Range.AutoFilter Field:=12
ActiveWorkbook.Save
Application.ScreenUpdating = True
End Sub

Related

Loop inserting worksheet name in column - mismatch error

Trying to do the following
1- Open directory with multiple workbooks (Origins), copy/paste
each worksheet into Master workbook (Destin)
2- insert in Columns 'A' in Master worksheet (Destin) with the name of each worksheet from dir (Origin) - the worksheets name contain the date
3- Finally, consolidate all worksheets in Master workbook (Destin) into 'Summary' sheet by copy/paste each
worksheet below the other (i.e. database format)
got step-1 to work....stuck now (step-2 mismatch error)
Option Explicit
Sub AllFiles()
'Application.EnableCancelKey = xlDisabled
Application.DisplayAlerts = True
Application.ScreenUpdating = False
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 lastrow As Long
' set master workbook
Set Masterwb = Workbooks("masterbook_AAFC.xlsm")
folderPath = "C:\Users\axchilmeran.G3NETWORK\Downloads\Master_AAFC\" 'contains folder path
If Right(folderPath, 1) <> "\" Then folderPath = folderPath & "\"
Filename = Dir(folderPath & "*.csv*")
Do While Filename <> ""
Set wb = Workbooks.Open(folderPath & Filename)
If Len(wb.Name) > 35 Then
MsgBox "Sheet's name can be up to 31 characters long, shorten the Excel file name"
wb.Close False
GoTo Exit_Loop
Else
' add a new sheet with the file's name (remove the extension)
Set NewSht = Masterwb.Worksheets.Add(After:=Masterwb.Worksheets(1))
NewSht.Name = Replace(wb.Name, ".pdf.csv", "")
End If
' loop through all sheets in opened wb
For Each sh In wb.Worksheets
' get the first empty row in the new sheet
Set FindRng = NewSht.Cells.Find(What:="*", Lookat:=xlPart, LookIn:=xlFormulas, SearchOrder:=xlByRows, SearchDirection:=xlPrevious, MatchCase:=False)
If Not FindRng Is Nothing Then ' If find is successful
PasteRow = FindRng.Row + 1
Else ' find was unsuccessfull > new empty sheet, should paste at the first row
PasteRow = 1
End If
sh.UsedRange.Copy
NewSht.Range("B" & PasteRow).PasteSpecial xlPasteValues
these 2 lines below giving me mismatch error!
**lastrow = NewSht.UsedRange.Rows(NewSht.UsedRange.Rows.Count).Row
Worksheets(NewSht).Range("A2:A" & lastrow).Value = NewSht.Name**
Next sh
wb.Application.CutCopyMode = False
wb.Close False
Exit_Loop:
Set wb = Nothing
Filename = Dir
Loop
Application.ScreenUpdating = True
Application.DisplayAlerts = True
End Sub

Loop & Search for Matching Worksheets in Separate Wkbks; Add Wksht if No Match Found

I have a series of workbooks by District, Territory, and Period that have monthly sales data for each combination of District, Territory, and Period. There is a master workbook for each District containing separate worksheets for each Territory. The monthly data appears in columns B:M.
I need to open each of the monthly District, Territory, and Period files, open the corresponding District's master workbook, search for a corresponding Territory, and paste that month's data in the column associated with that month (e.g., Feb. data is pasted in column C). This should be followed by closing the monthly file and loop to the next monthly file.
However, I need to have code for the possibility that a NEW Territory is added to a District in midyear--sometime after that District's master workbook was initially created.
The loop as written wants to jump from the open monthly file to the next part of the loop code that would create a new worksheet, but that is not what is needed.
Any suggestions for fixing this? Here is what I have so far:
Sub DSMReportsP02()
Application.ScreenUpdating = False
Application.EnableEvents = False
Dim DistrictDSM As Range, DistrictsDSMList As Range
Dim Period As String, Path As String, DistPeriodFile As String, Territory As String
Dim YYYY As Variant
Dim WBMaster As Workbook, DistMaster As Workbook, CurDstTerrFile As Workbook
Dim wsCount As Integer, x As Integer
Dim wsExists As Boolean
Set DistrictsDSMList = Range("E11:E" & Cells(Rows.Count, "E").End(xlUp).Row)
Set WBMaster = ActiveWorkbook
Period = Range("C6").Value
YYYY = Range("C8").Value
wsExists = False
For Each DistrictDSM In DistrictsDSMList.Cells
Workbooks.Open Filename:="H:\Accounting\Monthend " & YYYY & "\DSM Files\DSM Master Reports\" & DistrictDSM & ".xlsx"
Set DistMaster = ActiveWorkbook
wsCount = Application.Sheets.Count
Path = "H:\Accounting\Monthend " & YYYY & "\DSM Files\" & DistrictDSM & "\P02"
DistPeriodFile = Dir(Path & "\*.xlsx")
Do While DistPeriodFile <> ""
Workbooks.Open Filename:=Path & "\" & DistPeriodFile, UpdateLinks:=False
DistPeriodFile = Dir
Set CurDstTerrFile = ActiveWorkbook
Territory = CurDstTerrFile.Sheets("Index").Range("A3").Value
For x = 1 To wsCount
If DistMaster.Worksheets(x).name = Territory Then
CurDstTerrFile.Sheets("Index").Range("F20").Copy 'PM
DistMaster.Sheets(Territory).Activate
Range("C3").PasteSpecial Paste:=xlPasteValues
CurDstTerrFile.Sheets("Index").Range("J20").Copy 'XRA
DistMaster.Sheets(Territory).Activate
Range("C5").PasteSpecial Paste:=xlPasteValues
CurDstTerrFile.Sheets("Index").Range("N20").Copy 'CO-OP
DistMaster.Sheets(Territory).Activate
Range("C7").PasteSpecial Paste:=xlPasteValues
CurDstTerrFile.Sheets("Index").Range("S20").Copy 'VR
DistMaster.Sheets(Territory).Activate
Range("C9").PasteSpecial Paste:=xlPasteValues
CurDstTerrFile.Sheets("Index").Range("W20").Copy 'OVER & ABOVE
DistMaster.Sheets(Territory).Activate
Range("C11").PasteSpecial Paste:=xlPasteValues
CurDstTerrFile.Sheets("Index").Range("AA20").Copy 'SS
DistMaster.Sheets(Territory).Activate
Range("C13").PasteSpecial Paste:=xlPasteValues
CurDstTerrFile.Sheets("Index").Range("A3:D19").Copy 'COPY BTs by DISTRICT
WBMaster.Sheets("BTs by District").Activate
Range("A1000000").End(xlUp).Offset(1, 0).PasteSpecial Paste:=xlPasteValues
Exit For
End If
Next x
If wsExists = False Then '***********FIX THIS SECTION!!!*************************
Worksheets.Add after:=DistMaster.Worksheets(Worksheets.Count)
CurDstTerrFile.Sheets("Index").Range("A3").Copy 'COPY TERRITORY
ActiveSheet.name = "New Territory"
DistMaster.Sheets(Territory).Activate
Range("A1").PasteSpecial Paste:=xlPasteValues
End If
Dim WS As Worksheet, SheetXXX As Worksheet
Set WS = WBMaster.Sheets("ReptTemplate")
WS.Copy after:=Sheets(WBMaster.Sheets.Count)
Set SheetXXX = ActiveWorkbook.ActiveSheet
SheetXXX.name = Worksheets("ReptTemplate").Range("A1").Value
CurDstTerrFile.Close
Loop
Dim DistWS As Worksheet
Dim DistName As String
Dim wbNew As Workbook
DistName = Left(DistrictDSM, 6) & "*"
Set wbNew = Application.Workbooks.Add
For Each DistWS In WBMaster.Sheets
If DistWS.name Like DistName Then DistWS.Move after:=Sheets(wbNew.Sheets.Count)
Next DistWS
With wbNew
.SaveAs "H:\Accounting\Monthend " & YYYY & "\DSM Files\DSM Master Reports\" & DistrictDSM & ".xlsx"
.Close
End With
Next DistrictDSM
Application.EnableEvents = True
End Sub
I am sorry but I cannot comment (not enough reputation to comment on questions) or otherwise I would have asked a few question before posting this.
From what I understood. What you need is a logic/algorithm that checks whether a new sheet (new territory) is required be added to the master file before starting the copying process to the master file. If a sheet needs to be added, it should be added at the end of the master file.
The code below is a general code, but you should be able to tweak it easily to fit your purpose. The code below compares the worksheets in wb2 with wb1. if a sheet name in wb2 does not exist in wb1 it will be added to a new sheet at the end of wb1 with a name similar to the one in wb2.
This code should be placed immediately after both files are opened.
Sub Comapre_Sheets()
Dim wb1 As Workbook
Dim wb2 As Workbook
Dim wks1 As Worksheet
Dim wks2 As Worksheet
Dim bWorkSheet_Found As Boolean
Set wb1 = Workbooks("Book1") ''' Change this to the master file
Set wb2 = Workbooks("Book2") ''' Change this to the file that might have the new sheet/territory
For Each wks2 In wb2.Worksheets
bWorkSheet_Found = False
For Each wks1 In wb1.Worksheets
If wks1.name = wks2.name Then
bWorkSheet_Found = True
End If
Next wks1
If Not bWorkSheet_Found Then
wb1.Worksheets.Add(After:=Worksheets(wb1.Sheets.Count)).name = wks2.name
End If
Next wks2
End Sub
Hope this helps you

VBA Script to split all worksheets in a workbook to separate files

I have a script that does a vlookup for each sheet in workbook and then splits each worksheet into its own file. I have the below script, but it is not working. The vlookup portion is working fine, but I am having issues with the split. It doesn't fail and give me an error, it just doesn't do anything.
Sub Splitbook()
MyPath = "***Folder Location***"
For Each sht In Workbooks("PO135 Division 1.xlsx").Worksheets
sht.Copy
ActiveSheet.Cells.Copy
ActiveSheet.Cells.PasteSpecial Paste:=xlPasteValues
ActiveSheet.Cells.PasteSpecial Paste:=xlPasteFormats
ActiveWorkbook.SaveAs _
Filename:=MyPath & "\" & sht.Name & ".xlsx"
ActiveWorkbook.Close savechanges:=False
Next sht
End Sub
I need to split the files and then save them in a distinct folder("Folder Location")--this is just a placeholder for the time being, it would be updated prior to running the script--
Any thoughts? Appreciate the help!
Put this in a regular module:
Sub NewWb()
Dim ws As Worksheet
Dim wbActive As Workbook
Dim wbNew As Workbook
Dim x As Single
Application.ScreenUpdating = False
Set wbActive = ActiveWorkbook
For Each ws In wbActive.Worksheets
Set wbNew = Workbooks.Add
ws.Copy Before:=wbNew.Sheets(1)
abc = "C:\Files\" & ws.Name & ".xlsx"
Application.DisplayAlerts = False
wbNew.Sheets("Sheet1").Delete
Application.DisplayAlerts = True
wbNew.SaveAs Filename:=abc
wbNew.Close Saved = True
Next ws
Set ws = Nothing
Set wbActive = Nothing
Set wbNew = Nothing
Application.ScreenUpdating = True
End Sub

Excel VBA .SaveAs breaking in loop

I have an excel workbook broken out with multiple worksheets, 1 per customer. In my code, I am trying to save each individual customer worksheet as its own excel file. However, the .SaveAs command breaks the second time it triggers in the loop. Any pointers would be fantastic.
Dim SchedWorksheet As Worksheet
Dim SchedWorkbook As Workbook
Dim SchedName As String
Set SchedWorkbook = ActiveWorkbook
Set SchedWorksheet = ActiveSheet
Application.DisplayAlerts = False
For Each Worksheet In SchedWorkbook.Sheets
If Worksheet.Name = "Instructions" Or Worksheet.Name = "Invoice_Items"
Or Worksheet.Name = "Customers" Or _
Worksheet.Name = "Terms" Or Worksheet.Name = "Dilution_Type" Or
Worksheet.Name = "Approval_Status" Or _
Worksheet.Name = "Carriers" Then
GoTo NextSched
End If
If Worksheet.Name = "Invoices" Then
'basicScheduleFileName is global set at beginning of program
SchedName = basicScheduleFileName & "ALL"
Else
SchedName = Worksheet.Name
End If
'payoutFileName is global set at beginning of program
Worksheet.SaveAs Application.ActiveWorkbook.Path & "\" & payoutFileName
& "\Basic Schedule" & "\" & SchedName, xlOpenXMLWorkbook
NextSched:
Next Worksheet
The error on the second iteration is as follows:
Run-time error 1004 'Application-defined or object-defined error'
I have also attempted to run this loop using the SchedWorksheet object in lieu of Worksheet and get the error "method .SaveAs of object _Worksheet failed" on the second iteration.
Question I have code extremely similar to his code earlier in my program that takes a similar dataset and uses an exportAsFixedFormat call to save each worksheet as a PDF. Is there an equivalent for .xlsx? (.csv would be fine as well)
I don't know what value "payOutFileName" has so I left it out of the code. I also don't know the value for basicScheduleFileName so I set it to "Something." You will have to change that to whatever you need to change it too. This works fine when saving to my dir "C\Files" Might be a little buggy for you. Hopefully it will be a start.
Sub asdfghj()
Dim SchedWorkbook As Workbook
Dim SchedName As String
Dim basicScheduleFileName As String
Dim payoutFileName As String
Dim ws As Worksheet
Dim wb As Workbook
basicScheduleFileName = "Something"
Set SchedWorkbook = ActiveWorkbook
Application.DisplayAlerts = False
For Each ws In SchedWorkbook.Sheets
Debug.Print ws.Name
If ws.Name = "Instructions" Or ws.Name = "Invoice_Items" _
Or ws.Name = "Customers" Or _
ws.Name = "Terms" Or ws.Name = "Dilution_Type" Or _
ws.Name = "Approval_Status" Or _
ws.Name = "Carriers" Then
GoTo NextSched
End If
If ws.Name = "Invoices" Then
SchedName = basicScheduleFileName & "ALL" & ".xlsx"
Else
SchedName = ws.Name & ".xlsx"
End If
ws.Activate
' SaveAs Application.ActiveWorkbook.Path & "\" & payoutFileName & "\Basic Schedule" & "\" & SchedName, xlOpenXMLWorkbook
Set wb = Workbooks.Add
ws.Copy Before:=wb.Sheets(1)
wb.Sheets("Sheet1").Delete
wb.SaveAs Filename:="C:\Files\" & SchedName, FileFormat:= _
xlOpenXMLWorkbook, CreateBackup:=False
wb.Close
NextSched:
Next ws
End Sub
First off, thanks to everyone who took time and brainpower trying to figure out my issue. I finally figured out a fix that works.
First I made sure to get rid of ActiveWorkbook and ActiveSheet references to avoid any confusion in Excel.
Second As #NickSlash pointed out, it was likely that even if my code did work, it would save multiple copies of the same file under different names. So, to solve that while fixing my original issue, I changed my code to copy the worksheets that I need into a new workbook and save them that way:
Dim WS As Worksheet
Dim WB As Workbook
Dim NWB As Workbook
Dim SchedName As String
Set WB = Workbooks("Basic_Schedule-.xls")
WB.Activate
'Application.DisplayAlerts = False
For Each WS In WB.Sheets
WB.Activate
If WS.Name = "Instructions" Or WS.Name = "Invoice_Items" Or WS.Name = "Customers" Or _
WS.Name = "Terms" Or WS.Name = "Dilution_Type" Or WS.Name = "Approval_Status" Or _
WS.Name = "Carriers" Then
GoTo NextSched
End If
If WS.Name = "Invoices" Then
SchedName = basicScheduleFileName & "ALL" & ".xlsx"
Else
SchedName = WS.Name & ".xlsx"
End If
'Copy sheet to another WB
Set NWB = Workbooks.Add
WB.Activate
Sheets(WS.Name).Copy After:=NWB.Sheets(NWB.Sheets.Count)
NWB.Sheets("Sheet1").Delete
NWB.SaveAs filename:=basicScheduleFilePath & "\" & payoutFileName & "\Basic Schedule" & "\" & SchedName
NWB.Close
WB.Activate
NextSched:
Next WS
Instead of this:
'Copy sheet to another WB
Set NWB = Workbooks.Add
WB.Activate
Sheets(WS.Name).Copy After:=NWB.Sheets(NWB.Sheets.Count)
NWB.Sheets("Sheet1").Delete
NWB.SaveAs filename:=basicScheduleFilePath & "\" & payoutFileName & "\Basic Schedule" & "\" & SchedName
NWB.Close
WB.Activate
Do this -- you can avoid the "Activate" method call, and also if you have a reference to WS as an object, it's redundant to do WB.Sheets(WS.Name) when WS already refers to the same Worksheet.
'Copy sheet to another WB
WS.Copy '## Creates a new workbook with the copied sheet.
Set NWB = ActiveWorkbook
NWB.SaveAs filename:=basicScheduleFilePath & "\" & payoutFileName & "\Basic Schedule" & "\" & SchedName
NWB.Close

Sumif formula that Inserts variable worksheet name into named range of other workbook

As you can see in the code below, I matching worksheet names in different workbooks. Once the macro finds matching worksheet names it then is performing a SUMIF formula. The named range inside of the SUMIF formula is unique to each sheet but is consistent. (i.e. - Name of sheet is "Sheet1"...named range 1 is "Sheet1_WEEKENDING" and named range 2 is "Sheet1_FORECAST"); this is consistent through all sheets.
I want the SUMIF formula to have the worksheet variable in the named range. Example ws = sheet1
(Named range 1 = "ws_WEEKENDING" and named range 2 = "ws_FORECAST")
Code so far:
Public Sub Baseline()
Dim ws, sh As Worksheet
Dim wbMaster, wbVariance As Workbook
Dim fileOpen As Workbook
Dim folderPath As String
Const VPPName As String = "Master_Vpp.xlsm"
Const VarName As String = "Program Variance Report_Test.xlsm"
'*******************************************************************
'MUST place Master_VPP and Variance Report files in the same folder
Application.ScreenUpdating = False
folderPath = Application.ActiveWorkbook.Path & Application.PathSeparator 'assigning path to get to both workbooks folder
On Error Resume Next
fileOpen = Workbooks("Master_VPP.xlsm")
If fileOpen Is Nothing Then 'is not open
Set wbMaster = Application.Workbooks.Open(folderPath & VPPName)
End If
Set wbVariance = ActiveWorkbook 'setting variable quarter variance report
For Each ws In wbVariance.Sheets
Application.ScreenUpdating = False
ws.Activate
If (ws.Name <> "SUMMARY") And (ws.Name <> "Template") Then
For Each sh In wbMaster.Sheets
sh.Activate
If ws.Name = sh.Name Then
ws.Range("C20").Activate
ActiveCell.FormulaR1C1 = _
"=SUMIF(Master_VPP.xlsm!HNB_WEEKENDING,RC2,Master_VPP.xlsm!HNB_FORECAST)"
'"=SUMIF('[" & wbMaster & "]'!" & sh.Name & "_WEEKENDING,RC2,'[" & wbMaster & "]'!" & sh.Name & "_FORECAST)"
Selection.AutoFill Destination:=Range("C20:C33")
'Range("C20").Select
'ActiveCell.FormulaR1C1 = _
"=SUMIF('[" & wbMaster & "]'!" & ws.Name & "_WEEKENDING',RC2,'[" & wbMaster & "]'!" & ws.Name & "_FORECAST)"
'Selection.AutoFill Destination:=Range("C20:C33")
Else
GoTo Cont:
End If
Next sh
Else
GoTo Cont
Cont:
End If
Next ws
End Sub
Reviewing your code, it appears it never worked - I had assumed that it was only the formula that required adjusting. Perhaps this will do it:
Public Sub Baseline()
Dim ws As Worksheet, sh As Worksheet
Dim wbMaster As Workbook, wbVariance As Workbook
Dim fileOpen As Workbook
Dim folderPath As String
Const VPPName As String = "Master_Vpp.xlsm"
Const VarName As String = "Program Variance Report_Test.xlsm"
'*******************************************************************
'MUST place Master_VPP and Variance Report files in the same folder
Application.ScreenUpdating = False
folderPath = Application.ActiveWorkbook.Path & Application.PathSeparator 'assigning path to get to both workbooks folder
Application.ScreenUpdating = False
Set wbVariance = ActiveWorkbook 'setting variable quarter variance report
On Error Resume Next
Set fileOpen = Workbooks(VPPName)
On Error GoTo 0
If fileOpen Is Nothing Then 'is not open
Set fileOpen = Application.Workbooks.Open(folderPath & VPPName)
End If
For Each ws In wbVariance.Sheets
If (ws.Name <> "SUMMARY") And (ws.Name <> "Template") Then
On Error Resume Next
Set sh = fileOpen.Sheets(ws.Name)
On Error GoTo 0
If Not sh Is Nothing Then
With ws.Range("C20")
.FormulaR1C1 = _
"=SUMIF(" & VPPName & "!" & sh.Name & "_WEEKENDING,RC2," & VPPName & "!" & sh.Name & "_FORECAST)"
.AutoFill Destination:=ws.Range("C20:C33")
End With
Set sh = Nothing
End If
End If
Next ws
End Sub