Good morning,
I have two different workbooks (wb1 and wb2), each has two worksheets, "2018" and "2019", containing some data.
I'm trying to create a macro that takes an input with InputBox that has to be 2018 or 2019 and, depending on the choice, it has to insert a SUMIF formula into the worksheet whose name has been tapped in, in the second workbook, with reference to different columns of wb1.
The point is that, depending on what it is inserted in InputBox, the formula in wb2 has to reference to the worksheet "2018" or "2019" of wb1.
=SUMIF('[wb1.xlsm]2018'!$C$3:$C$4412;A3;'[wb1.xlsm]2018'!$K$3:$K$4412)
Above there is the formula that I have now. Is it possible to remove "2018" after the square bracket and add the variable related to InputBox?
Thanks for your help
Edit from comments:
I tried to modify the formula, using Application.SumIf. The problem is that it now gives me run-time error 1004 Application-defined or object-defined error on the line that starts with Sumact = Application...
year_check = InputBox("Insert the year you need to check")
schedule_worksheet = "Schedule - " & year_check
family_worksheet = "Family - " & year_check
Dim Sumact As Range
For i = 9 To 200
index_row = index_row + 1
Set Sumact = wbfu.Worksheets(family_worksheet).Range(Cells(2, index_row), Cells(2, index_row))
Sumact = SumIf(wb.Worksheets(schedule_worksheet).Range("C:C"), wb.Worksheets(schedule_worksheet).Range(Cells(1, index_row), Cells(1, index_row)), wb.Worksheets(schedule_worksheet).Range("K:K"))
Next i
I have filtered my cumulative sales from SalesMasterSheet to different sheets each named after each particular customer but I got stuck at trying to add excel formulas because my VBA code always clears content of the range of cells on sheetActive.
I have tried the special cell method so as to clear only constants but it doesn't work.
Any help would be appreciated.
below is my code:
Private Sub Worksheet_activate()
Dim i, LastRow
LastRow = Sheets("MasterSheet").Range("A" & Rows.Count).End(xlUp).Row
Sheets("ACCIMA").Range("A1:L500").ClearContents
For i = 2 To LastRow
If Sheets("MasterSheet").Cells(i, "C").Value = "ACCIMA" Then
Sheets("MasterSheet").Cells(i, "C").EntireRow.Copy _
Destination:=Sheets("ACCIMA").Range("A" & Rows.Count).End(xlUp).Offset(1)
End If
Next i
End Sub
So far what it does is copy entries with "ACCIMA" on column C from Mastersheet to sheet("ACCIMA"), but i would like to put a formula in sheet("ACCIMA") but because Sheets("ACCIMA").Range("A1:L500").ClearContents
all formulas clear once i make the sheet active.
Given the low amount of informations you give I sort of understood your problem this way:
If your code always clears content of the range of cells on the active sheet you should try to add the worksheet you are working on in your code, e.g.
cells(1,1).value = "test"
would turn into
worksheets("customer1").cells(1,1).value = "test"
After new informations:
Copy the content of your range "A1:K500", ignore the column "L" which has your formular and then add your formulars in column "L".
worksheets("customer1").cells(1,1).formula = "..."
Keep in mind, that your syntax for the formula changes in comparison with the synatx on the actual excel sheet.
e.g.:
=IF(A1="empty";"empty";"not empty")
Will turn into:
worksheets("customer1").cells(1,1).formula = "=IF(A1=""empty"",""empty"",""not empty"")"
So I had a code that was working. Basically pieces together different parts in cells A2 and A1 of each worksheet to create unique tab names. But I ran into a situation of duplicate tab names. So I adjusted the formula by making it a little longer to avoid these errors but now when I run the Macro I get Run-Time error '1004'. With no clue on why because nothing changed but the formula.
Here's the code:
Sub Tab_Name_Creation()
Dim s As Worksheet
Dim formula As String
For Each s In ActiveWorkbook.Worksheets
s.Activate
With ActiveWindow
.View = xlNormalView
End With
Next s
Call UnhideRows
formula = "=IF(R[-3]C=""Facility Variance Report"",IF(MID(R[-2]C,FIND("":"",R[-2]C)+2,20)=""Baptist Memorial Hos"",MID(R[-2]C,FIND(""_"",R[-2]C)+1,2)&""-""&TRIM((MID(R[-2]C,FIND("":"",R[-2]C)+2,17)))&IF(IFERROR(FIND(""West"",R[-2]C),0)>0,"" W"","""")&"" ""&MID(R[-2]C,FIND(CHAR(1),SUBSTITUTE(R[-2]C,""-"",CHAR(1),2))+1,3)&"" -FVar"",MID(R[-2]C,FIND(""_"",R[-2]C)+1,2)&""-""&TRIM(" & _
"2]C,FIND("":"",R[-2]C)+2,20)))&IF(IFERROR(FIND(""West"",R[-2]C),0)>0,"" W"","""")&""-FVar""),IF(MID(R[-2]C,FIND("":"",R[-2]C)+2,20)=""Baptist Memorial Hos"",MID(R[-2]C,FIND(""_"",R[-2]C)+1,2)&""-""&TRIM((MID(R[-2]C,FIND("":"",R[-2]C)+2,17)))&IF(IFERROR(FIND(""West"",R[-2]C),0)>0,"" W"","""")&"" ""&MID(R[-2]C,FIND(""-"",R[-2]C,FIND(""-"",R[-2]C)+1)+1,3)&""-LTM"",MID(" & _
"ND(""_"",R[-2]C)+1,2)&""-""&TRIM((MID(R[-2]C,FIND("":"",R[-2]C)+2,20)))&IF(IFERROR(FIND(""West"",R[-2]C),0)>0,"" W"","""")&""-LTM""))"
For i = 5 To ThisWorkbook.Worksheets.Count
Worksheets(i).Range("A4").NumberFormat = "General"
Worksheets(i).Range("A4") = formula
Next i
Call RenameFromA4
Call SortWorkBook
Call listsheets
MsgBox "Report Has Been Updated"
End Sub
To give you some background on the macro itself. I have a sheet with about 94 sheets with the tab names in account numbers which made it hard for people to understand. So i created this macro that first changes the workbook view to normal view, than unhide rows at the top of the spreadsheet, than inserts the formula that giving issue, than it renames the tabs, sort them and than create/organize a table of contents.
Any insight why I get run time error on line will be appreciated:
Worksheets(i).Range("A4") = formula
Example of the Formula
Cell A1 contains :LTM Income Statement
Cell A2 Contains : HM_LA_217368 - HM: St. Martin Hospital
The formula in excel: IF(A1="Facility Variance Report",IF(MID(A2,FIND(":",A2)+2,20)="Baptist Memorial Hos",MID(A2,FIND("_",A2)+1,2)&"-"&TRIM((MID(A2,FIND(":",A2)+2,17)))&IF(IFERROR(FIND("West",A2),0)>0," W","")&" "&MID(A2,FIND("-",A2,FIND("-",A2)+1)+1,3)&"-FVar",MID(A2,FIND("_",A2)+1,2)&"-"&TRIM((MID(2:2,FIND(":",A2)+2,20)))&IF(IFERROR(FIND("West",A2),0)>0," W","")&"-FVar"),IF(MID(A2,FIND(":",A2)+2,20)="Baptist Memorial Hos",MID(A2,FIND("_",A2)+1,2)&"-"&TRIM((MID(A2,FIND(":",A2)+2,17)))&IF(IFERROR(FIND("West",A2),0)>0," W","")&" "&MID(A2,FIND("-",A2,FIND("-",A2)+1)+1,3)&"-LTM",MID(A2,FIND("_",A2)+1,2)&"-"&TRIM((MID(A2,FIND(":",A2)+2,20)))&IF(IFERROR(FIND("West",A2),0)>0," W","")&"-LTM"))
Produces a result of "LA-St. Martin Hospital-LTM" So that will be the new tab name.
So I concatenated the formula to fit string :
formula = "=IF(R[-3]C=""Facility Variance Report"",IF(MID(R[-2]C,FIND("":"",R[-2]C)+2,20)=""Baptist Memorial Hos"",MID(R[-2]C,FIND(""_"",R[-2]C)+1,2)&""-""&TRIM((MID(R[-2]C,FIND("":"",R[-2]C)+2,17)))&IF(IFERROR(FIND(""West"",R[-2]C),0)>0,"" W"","""")&"" ""&MID(R[-2]C,FIND(""-"",R[-2]C,FIND(""-"",R[-2]C)+1)+1,3)&""-FVar""" & _
formula = formula & "MID(R[-2]C,FIND(""_"",R[-2]C)+1,2)&""-""&TRIM((MID(2:2,FIND("":"",R[-2]C)+2,20)))&IF(IFERROR(FIND(""West"",R[-2]C),0)>0,"" W"","""")&""-FVar"")" & _
formula = formula & "IF(MID(R[-2]C,FIND("":"",R[-2]C)+2,20)=""Baptist Memorial Hos"",MID(R[-2]C,FIND(""_"",R[-2]C)+1,2)&""-""&TRIM((MID(R[-2]C,FIND("":"",R[-2]C)+2,17)))&IF(IFERROR(FIND(""West"",R[-2]C),0)>0,"" W"","""")&"" ""&MID(R[-2]C,FIND(""-"",R[-2]C,FIND(""-"",R[-2]C)+1)+1,3)&""-LTM""" & _
formula = forumla & "MID(R[-2]C,FIND(""_"",R[-2]C)+1,2)&""-""&TRIM((MID(R[-2]C,FIND("":"",R[-2]C)+2,20)))&IF(IFERROR(FIND(""West"",R[-2]C),0)>0,"" W"","""")&""-LTM""))"
Still getting a error on the string
In Excel 2010, I am copying, via VBA code, worksheets from a Master workbook to a new workbook so that the individual new workbooks can each contain a set of data for different clients.
Some of the worksheets have tables of data pulled from an Access DB, and PivotTables based on that data set. My code copies the worksheet from the master to the new client workbook, updates the data on the worksheet, then updates the .PivotCache.SourceData to point to the new workbook.
This code was working just fine to update the .PivotCache.SourceData:
If XLClinic.PivotCaches.Count <> PivotCacheCount Then
Formula = NewSheet.PivotTables(1).PivotCache.SourceData
If InStr(1, Formula, "'") > 0 Then
Bracket = InStr(1, Formula, "]")
Formula = Replace(Formula, "'", "")
NewSheet.PivotTables(1).PivotCache.SourceData = Right(Formula, _
Len(Formula) - Bracket + 1)
End If
End If
I then changed my "Master" worksheet layout so that instead of just being some data on the worksheet, I actually defined it as a table, and I've manually updated the PivotTable(s) to point to the table name (I changed the table name to something consistent and relevant to the data set, instead of just TableX).
This code no longer work to change the .SourceData for the pivot table. When I attempt to execute it, I get:
Run-time error '1004':
Application-defined or object-defined error
When the data is simply formatted as a bunch of cells, the .SourceData value looks like this:
'\\server\share\full path[Workbook Name]Worksheet Name'!$A$4:$E$240
When I change the formatting of the data to a table, .SourceData now looks like this:
'\\server\share\full path\Workbook Name`!TableName
With this change in structure in mind, I changed my code to this:
If XLClinic.PivotCaches.Count <> PivotCacheCount Then
Formula = NewSheet.PivotTables(1).PivotCache.SourceData
If InStr(1, Formula, "'") > 0 Then
Bracket = InStr(1, Formula, "!")
NewSheet.PivotTables(1).PivotCache.SourceData = Right(Formula, Len(Formula) - Bracket)
End If
End If
Unfortunately, I'm still getting the Run-time error'1004'.
I have confirmed that the table in the destination workbook has the same name as the original, it's not getting renamed with a generic name (that's why I'm enforcing a specific name/table on my Master).
This is what I finally came up with:
If XLClinic.PivotCaches.Count <> PivotCacheCount Then
Formula = NewSheet.PivotTables(1).PivotCache.SourceData
Bracket = InStr(1, Formula, "!")
Formula = Right(Formula, Len(Formula) - Bracket)
NewPivotRange = NewSheet.Name & "!" & _
NewSheet.ListObjects(Formula).Range.Address(ReferenceStyle:=xlR1C1)
For Each PT In NewSheet.PivotTables
PT.ChangePivotCache XLClinic.PivotCaches.Create(SourceType:=xlDatabase, _
SourceData:=NewPivotRange)
Next
End If
The drawback to this is that it creates a new PivotCache for every single pivot table. When the workbook build is complete, I'll run through some other code I found that will eliminate all the duplicate Pivot Caches to help reduce the size of the workbook.
I've found you can also set the pivottable range for the first pivottable, then change the cache of all the other pivottables to the first pivottable's cache.
Dim sourceRange As String, sht As Worksheet, pvt As PivotTable, sourcePivot As String
sourceRange = "Sheet1!R1C1:R1000C9"
'OR if in a different workbook: sourceRange = "c:\filepath\[filename.xlsx]Sheet1!R1C1:R1000C9"
Set sht = ThisWorkbook.Worksheets("NewSheet")
sht.PivotTables(1).SourceData = sourceRange
sourcePivot = sht.Name & "!" & sht.PivotTables(1).Name
For Each pvt In sht.PivotTables
pvt.ChangePivotCache (sourcePivot)
Next
Debug.Print ThisWorkbook.PivotCaches.Count
I'm new to VBA and am trying to design a program that will go through a column with Strings in it and for every unique String name create a new worksheet object with that String value as its name and then copy and paste the values in that row to the new sheet. All identical Strings should then also have the values in their row copied over to the new sheet. The data is not sorted based on the Strings so I might have String a, String b, String a, in a column and I want both String a's to be a part of the same new sheet. Before I added a few lines of code to account for this everything was working fine, but now I'm getting an application defined or object defined error at an if statement that shouldn't be related to the added code. Here it is:
Sub FilterByClass()
Dim i As Long
Dim j As Long
Dim sheetName As String
Dim sheet As Worksheet
Dim book As Workbook
Dim k As Integer
ActiveSheet.Name = "AllClasses"
sheetName = Worksheets("AllClasses").Cells(2, 1).Value
Worksheets.Add
ActiveSheet.Name = sheetName
Worksheets("AllClasses").Activate
ActiveSheet.Rows("1:2").Copy
Worksheets(sheetName).Paste
j = 3
k = 0
For i = 3 To Rows.Count
If Worksheets("AllClasses").Cells(i, 1).Value <> Worksheets("AllClasses").Cells(i - 1, 1).Value Then //site of error
Worksheets("AllClasses").Range("1:1," & j & ":" & (i - 1)).Copy
Worksheets(Worksheets("AllClasses").Cells((i - 1), 1).Value).Paste
j = i
sheetName = Worksheets("AllClasses").Cells(i, 1).Value
For Each sheet In ActiveWorkbook //new added code block
If sheetName = sheet.Name Then k = 1
Next sheet
If k = 1 Then k = 0
Else
Worksheets.Add
ActiveSheet.Name = sheetName
Worksheets("AllClasses").Activate
End If
Next i
End Sub
Any help would be greatly appreciated.
ΒΈ
I've noticed a few things wrong with your code that are easier to point out in an answer rather than a comment.
1. Code not valid --Ignore this--
You seem to be missing 2 End Ifs in the code you posted. I can only assume it's just a copy-paste error, so I'll swiftly move on.
2. Line with comment "new added code block"
Your code says:
For Each sheet In ActiveWorkbook
you should replace that with this:
For Each sheet In ActiveWorkbook.Worksheets
The Workbook is not a collection of sheets, the workbook's .Worksheets function is.
3. Termination of the outer For loop
In the comments, you said that the original error happens in the first iteration of your loop inside the If statement, but I'm not convinced. Having had a quick play with your code, I think the error you're seeing ('1004' : "Application-defined or object-defined error") is a result of a different problem.
In my run-through of your code, this line in the Else block of If k = 1:
ActiveSheet.Name = sheetName
caused the error. That is because this line:
sheetName = Worksheets("AllClasses").Cells(i, 1).Value
returned sheetName = "".
This situation happens when a cell in position Cells(i, 1) is empty, which is entirely possible in your code since your outer For loop is iterating over all rows in the "AllClasses" sheet -- all 1048576 of them (in Excel 2007 and later versions). Unless you've got a value in every single row's column 1 (which I doubt), then at some point you'll meet a cell that is blank. Assigning that blank string to ActiveSheet.Name will cause the error you're seeing.
You can either hardcode the value of your outer For loop's terminating condition or you can use the various "tricks" to dynamically determine that value, e.g. Sheet.UsedRange.Rows.Count or Sheet.Cells(1048576, col).End(xlUp).row.