Create subroutines in one workbook that work on another - vba

I've created a button on one workbook that opens another macro-less workbook. transposeDataMatrices is the sub that will be run on the worksheets in the workbook that is opened:
Private Sub CommandButton21_Click()
Set BEEBook = ThisWorkbook
FileSelect = Application.GetOpenFilename(FileFilter:="Excel Files (*.xl*), *.xl*", Title:="Please select the report to import")
If FileSelect = "False" Then Exit Sub
Set ReportBook = Workbooks.Open(FileSelect)
transposeDataMatrices
End Sub
Within transposeDataMatrices is the following, heavily truncated code (ReportBook is a global variable for the workbook being worked on in trasposeDataMatrices; cArray is a global array):
Public Sub transposeDataMatrices()
ReportBook.Activate
rowCounter = finWkst.UsedRange.Rows.Count
For ii = 1 To wsCount
Worksheets(ii).Activate
pullModelData (ii) ' just pulls some data, off ii worksheet in ReportBook
ReDim indexIDArray(0 To 504) As Integer
Dim j as Integer: j = 0
For Each catName In cArray
Dim totRange As Range
Set catTitle = Worksheets(ii).UsedRange.Find(catName)
If Not catTitle Is Nothing Then
catTitle.Offset(2, 0).Offset(0, 1).Select
ReportBook.Worksheets(ii).Range(Selection, Selection.End(xlToRight).Offset(0, -1)).Select
ReportBook.Worksheets(ii).Range(Selection, Selection.End(xlDown)).Select
Set totRange = Selection
Else
Set totRange = Cells("A1")
EndIf
indexIDArray(j) = j
Next
equipModelVersion rowCounter, indexIDArray
rowCounter = finWkst.UsedRange.Rows.Count
Next ii
End Sub
Sub equipModelVersion(rowCounterDummy As Integer, indexArrayDummy() As String)
ReportBook.Activate
finWkst.Activate
iCol = 1:
Set indexRange = Range(Cells(rowCounterDummy + 1, iCol), Cells(rowCounterDummy + 1 + UBound(valueArrayDummy, 1), iCol))
Dim j As Integer: j = 0
For I = rowCounterDummy + 1 To rowCounterDummy + 1 + UBound(valueArrayDummy, 1)
Cells(I, iCol) = indexArrayDummy(j)
j = j + 1
Next
End Sub
Sub initializeWorkspace()
ReportBook.Activate
finWkst.Activate
Range("A1").Value = "IndexID"
Range("B1").Value = "ModelID"
Range("C1").Value = "UserVersion"
Range("D1").Value = "Equipment"
Range("E1").Value = "Date"
For ii = LBound(cArray) To UBound(cArray)
Cells(1, ii + 5).Value = cArray(ii)
Next
End Sub
I have two questions:
Firstly, when equipModelVersion gets run, it stores the values in the cells of the workbook on the worksheet where the button is located, rather than the workbook that is opened, in a sheet created to store the values.
How do I rectify that?
I tried activating that specific worksheet, using a with statement, and some other quick things I found on Stack Overflow, but nothing worked.
Secondly, when I was debugging the transposeDataMatrices and had it separately, the following line worked:
Set totRange = Range(Range(Selection, Selection.End(xlToRight).Offset(0, -1)), Selection.End(xlDown))
In the macro that I transferred into the workbook with the button, it no longer works, so I had to work around it with:
ReportBook.Worksheets(ii).Range(Selection, Selection.End(xlToRight).Offset(0, -1)).Select
ReportBook.Worksheets(ii).Range(Selection, Selection.End(xlDown)).Select
Set totRange = Selection
Just looks bad.
Why is VBA being so dumb about it, when the code is EXACTLY IDENTICAL, but expanded?

VBA is not smart, it will only do what you tell it to do not what you think you told it to do.
My guess is that somewhere the ReportBook.Worksheets(ii) is losing focus.
It is good practice to always declare the parent when using objects. The easy way is to declare that parent object is as a variable.
in this case:
Dim ws as worksheet
set ws = ReportBook.Worksheets(ii)
then the with the two lines in question use a with statment
with ws
Set totRange =.Range(Selection, Selection.End(xlDown))
end with
You should avoid using the .select command. See here for great information on that. Using it only dirties the code and makes it harder to find the errors.

Related

Generating vLookup-formula with over 250 "parts" with VBA

My questions is: How can I add multiple vLookup-formulas into one cell over VBA?
I know that I can add one vLookUp like this:
... = Application.WorksheetFunction.vLookUp("Search","Matrix","Index")
My Problem is: I have a workbook with 255 pages and in my "sum-sheet" I need variable formulas that search in those 255 worksheets for the data I need.
So the output of the macro in excel needs to be something like (all of in one cell):
=vLoookUp($A2;Sheet1!A1:A1000;2)+SVERWEIS($A2;Sheet2!A1:A1000;2)+ ...(255 times)
Is it even possible to do something like that with VBA?
This is the code I used to split the different options into the 255 sheets:
This is the code I wrote so far to split the different variations of stocks:
(Its somewhat working but I'm kind of sure its not very efficient, I'm new to all this Programming Stuff)
Sub Sheets()
Application.ScreenUpdating = False
ActiveWindow.WindowState = xlMinimized
Dim Data As String
Dim i As Long
Dim k As Long
Dim x As Long
Dim y As String
For i = 2 To 255
Sheetname = Worksheets("Input").Cells(i, 1).Value
Worksheets.Add.Name = Sheetname
ActiveSheet.Move After:=Worksheets(ActiveWorkbook.Sheets.Count)
x = 1
For k = 2 To 876
Data = Worksheets("Input").Cells(i, k).Value
y = Cells(1, x).Address(RowAbsolute:=False, ColumnAbsolute:=False)
BloomB = "=BDH(" & y & ",""TURNOVER"",""8/1/2011"",""4/30/2016"",""Dir=V"",""Dts=S"",""Sort=A"",""Quote=C"",""QtTyp=Y"",""Days=T"",""Per=cd"",""DtFmt=D"",""UseDPDF=Y"")"
Worksheets(Sheetname).Cells(1, x) = Data
Worksheets(Sheetname).Cells(2, x) = BloomB
x = x + 2
Next k
Application.Wait (Now + TimeValue("0:00:05"))
Next i
ActiveWindow.WindowState = xlMaximized
Application.ScreenUpdating = True
End Sub
Sorry, but this sounds like a very bad design. Maybe Access or SQL Server would be better suited for this kind of task. Also, you know the VLOOKUP function will return the first match, but no subsequent matches, right. Just want to make you aware of that. Ok, now try this.
Function VLOOKAllSheets(Look_Value As Variant, Tble_Array As Range, _
Col_num As Integer, Optional Range_look As Boolean)
''''''''''''''''''''''''''''''''''''''''''''''''
'Written by OzGrid.com
'Use VLOOKUP to Look across ALL Worksheets and stops _
at the first match found.
'''''''''''''''''''''''''''''''''''''''''''''''''
Dim wSheet As Worksheet
Dim vFound
On Error Resume Next
For Each wSheet In ActiveWorkbook.Worksheets
With wSheet
Set Tble_Array = .Range(Tble_Array.Address)
vFound = WorksheetFunction.VLookup _
(Look_Value, Tble_Array, _
Col_num, Range_look)
End With
If Not IsEmpty(vFound) Then Exit For
Next wSheet
Set Tble_Array = Nothing
VLOOKAllSheets = vFound
End Function
The full description of everything is here.
http://www.ozgrid.com/VBA/VlookupAllSheets.htm

Excel data not displaying

I have data that doesnt seem to be merging all the rows! I need it to merge even with empty columns.
For example:
On Sheet CPW, Column W is blank. So when merged all the entries for CPW should show blank in Column W and the information from Sheet CCI would only show.
That's just one example. There are many more on these two sheets.
This is my code for the merge. How can it be edited to do what I require?
Sub Combine()
Dim J As Integer
Dim wrk As Workbook 'Workbook object - Always good to work with object variables
Dim r1, r2, r3, r4, ra, rb, rc, rd, re, rf, rg As Range
Sheets("Sheet2").Select
Set r1 = Range("A:C")
Set r2 = Range("E:X")
Set r3 = Range("Y:AW")
Set r4 = Range("AX:BK")
Sheets("Sheet3").Select
Set ra = Range("A:A")
Set rb = Range("C:C")
Set rc = Range("B:B")
Set rd = Range("D:G")
Set re = Range("I:AL")
Set rf = Range("AM:AP")
Set rg = Range("AQ:BK")
Set wrk = Workbooks.Add
ActiveWorkbook.Sheets(2).Activate
Sheets(2).Name = "CPW"
r1.Copy Range("A1")
r2.Copy Range("D1")
r3.Copy Range("Y1")
r4.Copy Range("AY1")
Range("A1:BK100").Font.ColorIndex = 3
ActiveWorkbook.Sheets(3).Activate
Sheets(3).Name = "CCI"
ra.Copy Range("A1")
rb.Copy Range("B1")
rc.Copy Range("C1")
rd.Copy Range("D1")
re.Copy Range("H1")
rf.Copy Range("AM1")
rg.Copy Range("AQ1")
On Error Resume Next
Sheets(1).Select
Sheets(1).Name = "Combined"
Sheets(2).Activate
Range("A2").EntireRow.Select
Selection.Copy Destination:=Sheets(1).Range("A1")
For J = 2 To Sheets.Count
Sheets(J).Activate
Range("A2").Select
Selection.CurrentRegion.Select
Selection.Offset(1, 0).Resize(Selection.Rows.Count - 1).Select
Selection.Copy Destination:=Sheets(1).Range("A65536").End(xlUp)(2)
Sheets(1).Select
Range("A1:BK1000").Sort _
Key1:=Range("E1"), Key2:=Range("J1"), Header:=xlYes
Next
End Sub
Use of Select and Activate is not recommended (unless essential to the code’s objectives) because they are slow commands and are confusing.
You have blank columns because your copies do not line up. With the creation of the source ranges so far from their use, this is not obvious.
My macro achieves the same result as yours. I have bought all the code for copying together so it is much more obvious where you have left gaps. I have included questions where I suspect your code does not do what you want. I have included comments explaining aspects of your code I do not like.
Work through my code and study how I have achieved the same effects as yours. Come back with questions as necessary but the more you can understand on your own, the faster you will develop your skills.
Option Explicit
Sub Combine()
' Here it does not really matter since J is only used in a small block of
' code but avoid names like J. When you return to update this macro in
' 12 months will you remember what J is? I have a system of names that I
' have used for years. I can look at a macro I wrote 5 years ago and
' immediately know what all the variables. This speeds the work of
' remembering what the macro did. If you do not like my naming system,
' design your own but have a system.
' "Integer" defines a 16-bit integer which requires special processing on
' a post-16-bit computer. Use Long which defines a 32-bit integer
'Dim J As Integer
Dim InxWsht As Long
Dim WbkThis As Workbook
Dim Rng As Range
Dim Row1Next As Long
Dim WbkNew As Workbook
Dim WshtNew2 As Worksheet
Dim WshtNew3 As Worksheet
Dim WshtThis2 As Worksheet
Dim WshtThis3 As Worksheet
' ThisWorkbook is the workbook containing the macro. It is not
' necessarily the active workbook
Set WbkThis = ThisWorkbook
Set WshtThis2 = WbkThis.Worksheets("Sheet2")
Set WshtThis3 = WbkThis.Worksheets("Sheet3")
Set WbkNew = Workbooks.Add
Set WshtNew2 = WbkNew.Worksheets(2)
Set WshtNew3 = WbkNew.Worksheets(3)
WshtNew2.Name = "CPW"
WshtThis2.Range("A:C").Copy Destination:=WshtNew2.Range("A1")
' Note columns E:X are written to columns D:W. X is left blank
WshtThis2.Range("E:X").Copy Destination:=WshtNew2.Range("D1")
WshtThis2.Range("Y:AW").Copy Destination:=WshtNew2.Range("Y1")
' Note the previous destination end in column AW while the next
' starts with AY. Column AX is left blank.
WshtThis2.Range("AX:BK").Copy Destination:=WshtNew2.Range("AY1")
' Why are only the first hundred rows coloured red?
' Why don't you colour column BL?
WshtNew2.Range("A1:BK100").Font.ColorIndex = 3
WshtNew3.Name = "CCI"
WshtThis3.Range("A:A").Copy Destination:=WshtNew3.Range("A1")
' Did you mean to reverse columns B and C?
WshtThis3.Range("B:B").Copy Destination:=WshtNew3.Range("C1")
WshtThis3.Range("C:C").Copy Destination:=WshtNew3.Range("B1")
WshtThis3.Range("D:G").Copy Destination:=WshtNew3.Range("D1")
WshtThis3.Range("I:AL").Copy Destination:=WshtNew3.Range("H1")
WshtThis3.Range("AM:AP").Copy Destination:=WshtNew3.Range("AM1")
WshtThis3.Range("AQ:BK").Copy Destination:=WshtNew3.Range("AQ1")
'On Error Resume Next
' This statement means ignore all errors which you should never do.
' Use this statement so:
'On Error Resume Next
'Statement that may fail for reasons you cannot control or stop
'On Error GoTo 0
'If Err.Number = 0 Then
' No error
'Else
' Display Err.Description or take corrective action according
' to value of Err.Number
'End If
'Selection.CurrentRegion.Select
' Since you have just created the worksheet it is probably safe to
' use "CurrentRegion". However, Excel's definition of CurrentRegion
' is not always what you might expect.
With WbkNew
With .Worksheets(1)
.Name = "Combined"
' Did you mean to copy row 2?
WshtNew2.Rows(2).Copy Destination:=.Rows(1)
End With
Row1Next = 3 ' Next free row in worksheets(1)
For InxWsht = 2 To Worksheets.Count
' This Find searches backwards from A1 by row for the first cell
' containing a value. This will give you what you expect more
' often that CurrentRegion
With Worksheets(InxWsht)
Set Rng = .Cells.Find(What:="*", After:=.Range("A1"), _
SearchOrder:=xlByRows, _
SearchDirection:=xlPrevious)
If Rng Is Nothing Then
' Probably not necessary here but best to be safe. If a worksheet
' is empty Find will return Nothing
Else
.Rows("2:" & Rng.Row).Copy Destination:=WbkNew.Worksheets(1).Cells(Row1Next, 1)
' Unless I absolutely know that column A will be the last column with
' a value, I prefer to caluclate the next free row.
Row1Next = Row1Next + Rng.Row - 1
End If
End With
Next
' I do not see the point of having the Sort within the or Loop
With .Worksheets(1)
.Cells.Sort Key1:=.Range("E1"), Key2:=Range("J1"), Header:=xlYes
End With
End With
End Sub

Moving Data and Refencing Sheet Object

I am trying to automate a spreadsheet to transfer data from one sheet to another sheet depending on what the first 3 characters of the data is. So for example, for the data NDX 12/31/2012 P2600, I would like it to be placed in the NDX sheet. So I have an array (desArr()) that splits that data into different positions of the array, such that desArr(0) contains "NDX", desArr(1) contains "12/31/2012" and so on.
The part I am having trouble with is moving the data to the respective sheets. Specifically, I need a variable reference to these spreadsheets. For instant, take the NDX sheet. I know I can just do NDX.cells(1,1).Paste or Worksheets(NDX.Name).Cells(1,1).Paste and that would work, but what if I want to do that for multiple sheets? I could obviously use If statements to define each different instance, but I wanted to shorten my code. Hence, I am trying to make the reference to the sheet objects variable, i.e. desArr(0).Name, but it returns with an error (which I understand why). Anyone with suggestions on how to achieve this? I know one solution is to just use the name property of the worksheet, but I wanted to avoid the chance of my code failing if someone changed the name of the sheets.
So perhaps like:
Dim desArr() As String, desInfo As String, opType As String
Dim rNum As Long, cNum As Long, i As Long
Dim wb As Workbook
Dim ws As Worksheet
Dim sortRng As Range, findRng As Range
Dim j As Integer 'Throw away after testing
Dim test As String 'Throw away after testing
Dim k As Integer 'Throw away after testing
Application.ScreenUpdating = False
Application.DisplayAlerts = False
Set wb = ThisWorkbook
Set ws = wb.Worksheets(Import.Name)
With ws
rNum = .Range("C1048576").End(xlUp).Row
cNum = 6 'Number of used columns starting from left
Set sortRng = .Range(.Cells(3, 2), .Cells(rNum, cNum))
'Sort range according to Type and Description
sortRng.Sort _
Key1:=.Range("B1"), _
Key2:=.Range("C1")
'Apply conditional formatting
With sortRng.Columns(2)
.FormatConditions.AddUniqueValues
.FormatConditions(.FormatConditions.Count).SetFirstPriority
.FormatConditions(1).DupeUnique = xlDuplicate
With sortRng.Columns(2).FormatConditions(1)
.Interior.PatternColorIndex = xlAutomatic
.Interior.Color = 13551615
.Interior.TintAndShade = 0
.StopIfTrue = False
End With
End With
For i = 0 To (rNum - 2)
With sortRng.Cells(i + 1, 2)
If .DisplayFormat.Interior.Color = "13551615" Then
j = 0
While (.Value = .Offset(j + 1, 0).Value And .Offset(0, 1).Value = .Offset(j + 1, 1).Value)
j = j + 1
Wend
If (j <> 0) Then 'There are duplicates
End If
End If
'Converting the description to format used for classification
If .Offset(0, -1) = "Ext Option" Then
desArr = Split(.Value, " ")
If Not (Left(.Value, 3) = "SX5" Or Left(.Value, 3) = "UKX") Then
'check if it's a call or put
If Left(desArr(3), 1) = "C" Then
opType = "Call"
ElseIf Left(desArr(3), 1) = "P" Then
opType = "Put"
Else
opType = "N/A"
End If
desInfo = Format(desArr(2), "mmmdd") & " " & Right(Trim(desArr(3)), Len(Trim(desArr(3))) - 1) & " " & opType
Else
'check if it's a call or put
If Left(desArr(2), 1) = "C" Then
opType = "Call"
ElseIf Left(desArr(2), 1) = "P" Then
opType = "Put"
Else
opType = "N/A"
End If
desInfo = Format(desArr(1), "mmmdd") & " " & Right(Trim(desArr(2)), Len(Trim(desArr(2))) - 1) & " " & opType
End If
End If
End With
Next i
End With
Application.ScreenUpdating = True
Application.DisplayAlerts = True
End Sub
Except that NDX would have to be variable as which worksheet to move the data to depends on the data.
You can use the codename property of the worksheets. If you use NDX.Cells(1,1), NDX is the codename of the sheet. simply search all worksheets, e.g.:
Function GetWorksheet(byval withCodename as String) as Worksheet
Dim sheetVar as Worksheet
For each sheetVar in ThisWorkbook.Worksheets
If sheetVar.CodeName = withCodename Then
Set GetWorksheet = sheetVar
End if
Next
End Function
You could:
Prevent user from renaming sheets
You wrote: "I wanted to avoid the chance of my code failing if someone changed the name of the sheets."
Well, the user can't do this:
If you protect the workbook. You can do this manually in the ribbon (Review > Changes > Protect workbook), or programmatically like this:
ThisWorkbook.Protect 'optionally, add a password -- see documentation for Protect
This will entirely prevent the user from changing sheet names.

Excel VBA loop through worksheets fails

Edit: I took all you advice and edited my code. Now it works!!!
Thank you.
Here is the new code:
Sub WorksheetLoop()
Dim AllWorksheets As Integer
Dim Worksheet As Integer
AllWorksheets = ActiveWorkbook.Worksheets.Count
For Worksheet = 2 To AllWorksheets
Sheets(1).Select
Cells(10, Worksheet).Value = Sheets(Worksheet).TextBoxes(2).Text
Cells(13, Worksheet).Value = Sheets(Worksheet).TextBoxes(3).Text
Cells(18, Worksheet).Value = Sheets(Worksheet).TextBoxes(1).Text
Cells(24, Worksheet).Value = Sheets(Worksheet).TextBoxes(5).Text
Cells(34, Worksheet).Value = Sheets(Worksheet).TextBoxes(6).Text
Cells(34, Worksheet).Value = Sheets(Worksheet).TextBoxes(4).Text
Next Worksheet
End Sub
Original Problem
So there is an excel document, which contains an amount of worksheets.
On the first sheet an overview should be created by the script.
It should start in the 2nd worksheet and should write the content of the textboxes (please don't ask why there are textboxes...) to Cell B10, B13, anso so on.
Then the script should go to worksheet 3 and the content of the textboxes should go to C10, C13,...
You get the idea...
I know that this is only possible to Z....
But why do I keep getting error messages?
My VBA knowlage is very small, so sorry for obvious errors.
Edit: I took the advice about the spaces around &
But I still get "object doesn't support this property or method"
Sub WorksheetLoop()
Dim AllWorksheets As Integer
Dim Worksheet As Integer
AllWorksheets = ActiveWorkbook.Worksheets.Count
For Worksheet = 2 To AllWorksheets
For CellAscii = 66 To (AllWorksheet + 66)
Cell = Chr(CellAscii)
Sheets(1).Select
Range(Cell & "10").Value = Sheets(Worksheet).TextBox2.Text
Range(Cell & "13").Value = Sheets(Worksheet).TextBox3.Text
Range(Cell & "18").Value = Sheets(Worksheet).TextBox1.Text
Range(Cell & "24").Value = Sheets(Worksheet).TextBox5.Text
Range(Cell & "30").Value = Sheets(Worksheet).TextBox6.Text
Range(Cell & "34").Value = Sheets(Worksheet).TextBox4.Text
Next CellAscii
Next Worksheet
End Sub
Just try the following when trying to access textboxes:
Sheets("SheetName").TextBoxes("TextBox Name").Text
Verify that your "SheetName" and "TextBox Name" are correct.
Hope this was usefull for you.
Range doesn't take a reference of schema Ay, it takes one with RyCx.
Anyway use SheetX.Cell to access a particular cell in a particular row and column.
You loop through cells like this:
Sub MyLoop()
For RowCounter = 1 To 20
For ColumnCounter = 1 To 20
Set curCell = Worksheets("Sheet1").Cells(RowCounter , ColumnCounter)
If Abs(curCell.Value) < 0.01 Then curCell.Value = 0
Next ColumnCounter
Next RowCounter
End Sub
The main error in your code is that there is no space before and after &
Change Range(Cell&"10").Value to Range(Cell & "10").Value. Similarly for the rest and your code will run just fine :)

Search for multiple phrase; copy to single sheet across multiple sheets

I am using Microsoft Excel to keep track of tasks. I use a different "sheet" for each job. The structure is with regards to columns and data. I have been trying to create a VBA script that would accomplish the following:
Search sheets 1 - X for a value of "Open" or "Past Due" in a row
Copy all rows with those values into a single sheet (such as a ledger) starting at row 3 (so I can add the headers of the template)
Add a column A with the sheet name so that I know what job it came from.
Run this to my hearts obsessive compulsive behavior pleasure to update with new items
I have been using the following posts to help guide me:
Search a specific word and copy line to another Sheet <- which was helpful but not quite right...
Copying rows to another worksheet based on a search on a grid of tags <-- also helpful, but limited to the activesheet and not looping correctly with my modifications...
The last two evenings have been fun, but I feel like I may be making this harder than necessary.
I was able to create a VBA script (edited from another post here) to sweep through all the worksheets, but it was designed to copy all data in a set of columns. I tested that and it worked. I then merged the code base I was using to identify "Open" or "Past Due" in column C (that worked for only the activesheet) into the code. I marked up my edits to share here. At this point it is not functioning, and I have walked myself dizzy. Any tips on where I fubar-ed the code would be appreciated. My code base I working from is:
Sub SweepSheetsCopyAll()
Application.ScreenUpdating = False
'following variables for worksheet loop
Dim W As Worksheet, r As Single, i As Single
'added code below for finding the fixed values on the sheet
Dim lastLine As Long
Dim findWhat As String
Dim findWhat1 As String
Dim findWhat2 As String
Dim toCopy As Boolean
Dim cell As Range
Dim h As Long 'h replaced i variable from other code
Dim j As Long
'replace original findWhat value with new fixed value
findWhat = "Open"
'findWhat2 = "Past Due"
i = 4
For Each W In ThisWorkbook.Worksheets
If W.Name <> "Summary" Then
lastLine = ActiveSheet.UsedRange.Rows.Count 'Need to figure out way to loop all rows in a sheet to find last line
For r = 4 To lastLine 'formerly was "To W.Cells(Rows.Count, 1).End(xlUp).Row"
'insert below row match search copy function
For Each cell In Range("B1:L1").Offset(r - 1, 0)
If InStr(cell.Text, findWhat) <> 0 Then
toCopy = True
End If
Next
If toCopy = True Then
' original code Rows(r).Copy Destination:=Sheets(2).Rows(j)
Range(W.Cells(r, 1), W.Cells(r, 12)).Copy _
ThisWorkbook.Worksheets("Summary").Cells(i, 1)
j = j + 1
End If
toCopy = False
'Next
'end above row match search function
'below original code that copied everything from whole worksheet
' If W.Cells(r, 1) > 0 Then
' Range(W.Cells(r, 1), W.Cells(r, 12)).Copy _
' ThisWorkbook.Worksheets("Summary").Cells(i, 1)
' i = i + 1
' End If
Next r
End If
Next W
End Sub
The working code base to sweep through all the sheets was:
Sub GetParts()
Application.ScreenUpdating = False
Dim W As Worksheet, r As Single, i As Single
i = 4
For Each W In ThisWorkbook.Worksheets
If W.Name <> "Summary" Then
For r = 4 To W.Cells(Rows.Count, 1).End(xlUp).Row
If W.Cells(r, 1) > 0 Then
Range(W.Cells(r, 1), W.Cells(r, 3)).Copy _
ThisWorkbook.Worksheets("Summary").Cells(i, 1)
i = i + 1
End If
Next r
End If
Next W
End Sub
And the copy the matched data from the Activesheet is as follows:
Sub customcopy()
Application.ScreenUpdating = False
Dim lastLine As Long
Dim findWhat As String
Dim findWhat1 As String
Dim findWhat2 As String
Dim toCopy As Boolean
Dim cell As Range
Dim i As Long
Dim j As Long
'replace original findWhat value with new fixed value
findWhat = "Open"
'findWhat2 = "Past Due"
lastLine = ActiveSheet.UsedRange.Rows.Count 'Need to figure out way to loop through all sheets here
'below code does nice job finding all findWhat and copying over to spreadsheet2
j = 1
For i = 1 To lastLine
For Each cell In Range("B1:L1").Offset(i - 1, 0)
If InStr(cell.Text, findWhat) <> 0 Then
toCopy = True
End If
Next
If toCopy = True Then
Rows(i).Copy Destination:=Sheets(2).Rows(j)
j = j + 1
End If
toCopy = False
Next
i = MsgBox(((j - 1) & " row(s) were copied!"), vbOKOnly, "Result")
Application.ScreenUpdating = True
End Sub
You should look into this Vba macro to copy row from table if value in table meets condition
In your case, you would need to create a loop, using this advanced filter to copy the data to your target range or array.
If you need further advice, please post your code, and where you are stuck with it.