I'm trying to be able to use this macro to create this pivot table each day on the same worksheet name. The only thing that will change is the datasource row as I never know how many rows it will be. I tried to set the entire string into the CurSourceData variable and then just use that but it fails and says invalid arg.
Any ideas would be helpful.
Sheets("Cases 23+ Day (Due Today)").Select
Range("A1").Select
Selection.End(xlDown).Select
Selection.End(xlDown).Select
CurRow = ActiveCell.Row
CurSourceData = "Cases 23+ Day (Due today)!R1C2:R" & CurRow & "C20"
ActiveWorkbook.PivotCaches.Create(SourceType:=xlDatabase, SourceData:= _
CurSourceData, Version:=xlPivotTableVersion14). _
CreatePivotTable TableDestination:="Master Summary!R3C7", TableName:= _
"PivotTable3", DefaultVersion:=xlPivotTableVersion14
Sheets("Master Summary").Select
Cells(3, 7).Select
ActiveSheet.PivotTables("PivotTable3").AddDataField ActiveSheet.PivotTables( _
"PivotTable3").PivotFields("Status"), "Count of Status", xlCount
With ActiveSheet.PivotTables("PivotTable3").PivotFields("Status")
.Orientation = xlRowField
.Position = 1
End With
The SourceData argument of PivotCaches.Create is either a Range or a Connection. I think there's also a problem with the space in your sheet name and the answer is to use single quotes. Try :
Set CurSourceData = Worksheets("Cases 23+ Day (Due today)").Range("B1", "T" & CurRow)
(I detest R1C1 notation and couldn't work out how to use it here.)
This has worked for me, assuming your data set starts in cell A1:
Dim MyRange As Range
Dim lrow As Long
Dim lcol As Long
lrow = ActiveSheet.Cells(Application.Rows.Count, 1).End(xlUp).Row
lcol = ActiveSheet.Cells(1, Application.Columns.Count).End(xlToLeft).Column
Set MyRange = ActiveSheet.Cells(1, 1).Resize(lrow, lcol)
Good luck!
Related
I am looking for some help modifying existing code in a worksheet that I had created a while back to copy and paste a range from a row rather than the entire row itself.
The original code, which has worked perfect in the original intended function, it would search column A in the Data worksheet for a specified match. it would then copy that row into a specified worksheet and paste each match as a new row.
What I have been trying to modify the code to do now is perform that same search of column A for either " New, Existing Being Removed, Existing To Remain". When finding one of the 3 options it would then copy the data from columns b:g of that matching row and paste it into the rent worksheet starting at a specified cell. For instance rows marked as Existing to remain would need to star being pasted at cell B3, Existing being removed cell m3, and New cell x3. In total there would not be more than 20 rows from the data sheet that would need to be copied and pasted appropriately.
The code below is the current working code that will search, copy, and paste the entire matching row. Not being extremely proficient with VBA code I didn't want to post the muddled mess that I had made of the original code.
Edit With Photos*
#Toddleson I made the changes you suggested but ended up getting an error with the copyfrom.copy line. It is probably much easier to see what I am trying to accomplish visually. In the Data sheet image link below you will see that row A is where the search occurs. For each match it will copy the values from columns B:G of that row and then paste that into the rent sheet.
If you take a look at the rent image you will see that it is broken into the 3 cooresponding sections. From the match that was found in the cooresponing deisgnation from column A in the data sheet it will then paste the information from columns B:G in the Data to the B:G columns in the Rent sheet.
Data Sheet
Rent
Private Sub CommandButton4_Click()
Dim wb1 As Workbook, wb2 As Workbook
Dim ws1 As Worksheet, ws2 As Worksheet
Dim copyFrom As Range
Dim lRow As Long '<~~ Not Integer. Might give you error in higher versions of excel
Dim strSearch As String
Set wb1 = ThisWorkbook
Set ws1 = wb1.Worksheets("Data")
strSearch = "New"
With ws1
.AutoFilterMode = False
lRow = .Range("A" & .Rows.Count).End(xlUp).Row
With .Range("A1:A" & lRow)
.AutoFilter Field:=1, Criteria1:="=*" & strSearch & "*"
Set copyFrom = .Resize(lRow - 1, 7)
End With
.AutoFilterMode = False
End With
Set ws2 = wb1.Worksheets("Rent")
With ws2
If Application.WorksheetFunction.CountA(.Cells) <> 0 Then
lRow = .Cells.Find(What:="*", _
After:=Range("p3"), _
Lookat:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByRows, _
SearchDirection:=xlPrevious, _
MatchCase:=False).Row
Else
lRow = 1
End If
copyFrom.Copy ws2.Cells(3, 16).Resize(copyFrom.Rows.Count, copyFrom.Columns.Count)
End With
strSearch = "Existing Being Removed"
With ws1
.AutoFilterMode = False
lRow = .Range("A" & .Rows.Count).End(xlUp).Row
With .Range("A1:A" & lRow)
.AutoFilter Field:=1, Criteria1:="=*" & strSearch & "*"
Set copyFrom = .Offset(1, 0).SpecialCells(xlCellTypeVisible).EntireRow
End With
.AutoFilterMode = False
End With
Set ws2 = wb1.Worksheets("Rent")
With ws2
If Application.WorksheetFunction.CountA(.Cells) <> 0 Then
lRow = .Cells.Find(What:="*", _
After:=Range("p19"), _
Lookat:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByRows, _
SearchDirection:=xlPrevious, _
MatchCase:=False).Row
Else
lRow = 1
End If
copyFrom.Copy ws2.Cells(3, 16).Resize(copyFrom.Rows.Count, copyFrom.Columns.Count)
End With
strSearch = "Existing To Remain"
With ws1
.AutoFilterMode = False
lRow = .Range("A" & .Rows.Count).End(xlUp).Row
With .Range("A1:A" & lRow)
.AutoFilter Field:=1, Criteria1:="=*" & strSearch & "*"
Set copyFrom = .Offset(1, 0).SpecialCells(xlCellTypeVisible).EntireRow
End With
.AutoFilterMode = False
End With
Set ws2 = wb1.Worksheets("Existing To Remain")
With ws2
If Application.WorksheetFunction.CountA(.Cells) <> 0 Then
lRow = .Cells.Find(What:="*", _
After:=.Range("p35"), _
Lookat:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByRows, _
SearchDirection:=xlPrevious, _
MatchCase:=False).Row
Else
lRow = 1
End If
copyFrom.Copy ws2.Cells(3, 16).Resize(copyFrom.Rows.Count, copyFrom.Columns.Count)
End With
End Sub
I basically have some data and I need to count how many times each row (titled "Process") occurs (using VBA). I used the built-in Excel macro, and used a pivot table to count the number of instances of each row, however, the problem is that when I run the macro, it only returns the total count of process.
This is my code:
FinalRow = Cells(Rows.Count, 1).End(xlUp).Row
DataSheet = ActiveSheet.Name
Sheets.Add
newsheet = ActiveSheet.Name
ActiveWorkbook.PivotCaches.Create(SourceType:=xlDatabase, SourceData:= _
DataSheet & "!R1C1:R" & FinalRow & "C52", Version:=6).CreatePivotTable TableDestination:= _
newsheet & "!R3C1", TableName:="PivotTable24", DefaultVersion:=6
Sheets(newsheet).Select
Cells(3, 1).Select
With ActiveSheet.PivotTables("PivotTable24").PivotFields("Process")
.Orientation = xlRowField
.Position = 1
End With
ActiveSheet.PivotTables("PivotTable24").AddDataField ActiveSheet.PivotTables( _
"PivotTable24").PivotFields("Process"), "Count of Process", xlCount
End Sub
If I remove the code between End With and End Sub, I get a pivot table with the rows as the list of processes. But when I add those two lines, I just get a value titled "Count of Process" with the Grand Total value. I am pretty sure that the issue lies somewhere there. Thanks.
I am trying to accelerate my Excel VB Macro.
I have tried the 5 alternatives below.
But I wonder if I could shorten the execution further.
I found 2 alternatives in User Blogs which I could not get to work.
One alternative is also found in a User Blog but do not understand.
Sub AccelerateMacro()
'
' v1 052817 by eb+mb
' Macro to copy as fast as possible sheet from one workbook into another workbooks
' Declarations for variables are not shown to make code example more legible
' Macro is stored in and run from "DestinationWorkBook.xlsm"
StartTime = Timer
Application.ScreenUpdating = False
Application.DisplayAlerts = False
Alternative = "First"
If Alternative = "First" Then
Workbooks.Open Filename:="SourceWorkBook.xls"
Cells.Select
Selection.Copy
Windows("DestinationWorkBook.xlsm").Activate
Sheets("DestinationSheet").Select
Range("A1").Select
ActiveSheet.Paste
Windows("SourceWorkBook.xls").Activate
ActiveWorkbook.Close
End If
If Alternative = "Second" Then
Workbooks.Open Filename:="SourceWorkBook.xls", ReadOnly:=True
Cells.Select
Selection.Copy
Windows("DestinationWorkBook.xlsm").Activate
Sheets("DestinationSheet").Select
Range("A1").Select
ActiveSheet.Paste
Workbooks("SourceWorkBook.xls").Close SaveChanges:=False
End If
If Alternative = "Third" Then
' I could not get this alternative to work
Workbooks.Open("SourceWorkBook.xls").Worksheets("SourceSheet").Copy
Workbooks.Open("DestinationWorkBook.xlsm").Worksheets("DestinationSheet").Range("A1").PasteSpecial
End If
If Alternative = "Fourth" Then
' I could not get this alternative to work
Workbooks.Open("DestinationWorkBook.xlsm").Worksheets("DestinationSheet").Range("A1") = Workbooks.Open("SourceWorkBook.xls").Worksheets("SourceSheet")
End If
If Alternative = "Fifth" Then
' I don't understand the code in this alternative
Dim wbIn As Workbook
Dim wbOut As Workbook
Dim rSource As Range
Dim rDest As Range
Set wbOut = Application.Workbooks.Open("DestinationWorkBook.xlsm")
Set wbIn = Application.Workbooks.Open("SourceWorkBook.xls")
With wbIn.Sheets("SourceSheet").UsedRange
wbOut.Sheets("DestinationSheet").Range("A1").Resize(.Rows.Count, .Columns.Count) = .Value
End With
SecondsElapsed = Round(Timer - StartTime, 2)
MsgBox "This code ran successfully in " & SecondsElapsed & " seconds", vbInformation
End Sub
Instead of using UsedRange, find the actual Last Row and Last Column and use that range. UsedRange may not be the range that you think it is :). You may want to see THIS for an explanation.
See this example (UNTESTED)
Sub Sample()
Dim wbIn As Workbook, wbOut As Workbook
Dim rSource As Range
Dim lRow As Long, LCol As Long
Dim LastCol As String
Set wbOut = Workbooks.Open("DestinationWorkBook.xlsm")
Set wbIn = Workbooks.Open("SourceWorkBook.xls")
With wbIn.Sheets("SourceSheet")
'~~> Find Last Row
lRow = .Cells.Find(What:="*", _
After:=.Range("A1"), _
Lookat:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByRows, _
SearchDirection:=xlPrevious, _
MatchCase:=False).Row
'~~> Find Last Column
LCol = .Cells.Find(What:="*", _
After:=.Range("A1"), _
Lookat:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByColumns, _
SearchDirection:=xlPrevious, _
MatchCase:=False).Column
'~~> Column Number to Column Name
LastCol = Split(Cells(, LCol).Address, "$")(1)
'~~> This is the range you want
Set rSource = .Range("A1:" & LastCol & lRow)
'~~> Get the values across
wbOut.Sheets("DestinationSheet").Range("A1:" & LastCol & lRow).Value = _
rSource.Value
End With
End Sub
Sorry about the flury of posting, I am trying to finish a project (there always seems to be one more thing)
I am tring to auto sort to last column starting at F2 I have the following but is not working
Thanks
Sub Sort()
Dim lastRow As Long
Dim lastCol As Long
Dim ws As Worksheet
Set ws = Sheets("sheet1")
lastRow = ws.Range("F" & ws.Rows.Count).End(xlUp).Row
lastCol = Cells(2, ws.Columns.Count).End(xlToLeft).Column
With Sheets("Sheet1")
ws.Range(ws.Range("F2"), ws.Cells(lastRow, lastCol)).Sort _
Key1:=Range("lastCol"), Order1:=xlAscending, Header:=xlNo, _
OrderCustom:=1, MatchCase:=False, Orientation:=xlTopToBottom, _
DataOption1:=xlSortNormal
End With
End Sub
The value for Key1 must be a range. You are trying to use the number that is the last column, and that won't work even if you remove the quotation marks.
Replace Key1:=Range("lastCol")
with Key1:=Cells(2, lastCol)
Note that you can use the GetColumnLetter function I included in my previous answer to get the letter for the lastCol column. If you have the letter, you can use this syntax instead of the Cells version:
Key1:=Range(myCol & 2)
To make sure you know what you are sorting, you can add a little bit of debugging code. You can also use the Immediate window and the Watch window to figure this out.
Replace your entire sub with this:
Sub Sort()
Dim lastRow As Long
Dim lastCol As Long
Dim ws As Worksheet
Dim rng As Range
Dim sortRng As Range
Set ws = Sheets("sheet1")
lastRow = ws.Range("F" & ws.Rows.Count).End(xlUp).Row
lastCol = Cells(2, ws.Columns.Count).End(xlToLeft).Column
Set rng = ws.Range(ws.Range("F2"), ws.Cells(lastRow, lastCol))
Set sortRng = ws.Cells(lastRow, lastCol)
MsgBox "I will sort this range: " & rng.Address & _
" using this column: " & sortRng
rng.Sort Key1:=sortRng, Order1:=xlAscending, Header:=xlNo, _
OrderCustom:=1, MatchCase:=False, Orientation:=xlTopToBottom, _
DataOption1:=xlSortNormal
End Sub
I am creating a Macro to run consecutively on about 25 sheets, where I am naming a cells in a specific column. I have the code for filling to end, and for changing sheets. But when I combine the codes, I am getting a warning:
Compile Error: Duplicate declaration in current scope
When I remove the DIM definition, it will run on the consecutive sheets, but only to the end of the first sheet. My goal is to have each sheet dynamically filled to end in column N with a set name for each.
Here is the code I was working on
Sub Mailbox_Name()
'
' Mailbox_Name Macro
' Adds Mailbox Name to Each Sheet
'
Dim LR As Long
LR = Cells.Find(What:="*", SearchDirection:=xlPrevious, SearchOrder:=xlByRows).Row
Range("N1").Select
ActiveCell.FormulaR1C1 = "Mailbox"
Range("N2").Select
ActiveCell.FormulaR1C1 = "ACC"
Range("N2").Select
Selection.AutoFill Destination:=Range("N2:N" & LR)
Range("N2:N" & LR).Select
Selection.Copy
Sheets("ACPR").Select
Dim LR As Long
LR = Cells.Find(What:="*", SearchDirection:=xlPrevious, SearchOrder:=xlByRows).Row
Range("N1").Select
ActiveCell.FormulaR1C1 = "Mailbox"
Range("N2").Select
ActiveCell.FormulaR1C1 = "ACPR"
Range("N2").Select
Selection.AutoFill Destination:=Range("N2:N" & LR)
Range("N2:N" & LR).Select
End Sub
Thanks for any help you can provide!
Just read what the error is telling you - you have a duplicate declaration. Sure enough, in your code you have Dim LR As Long twice.