Excel to dynamic Word table - vba

I am a VBA newb and am having an extremely difficult time trying to write some code for this solution. Any help would be greatly appreciated!
Within MS Word, I need to look in one Excel workbook across a worksheet and copy/paste the data that fits my criteria into a two-column table:
Start in Row 6 of the worksheet, look within range D6:M6. If D6:M6 is blank, then go to the next row. If any cell in D6:M6 has data, copy the data from C6 and paste it in the first row of a table (preferably merged across two columns). Then, copy the data from Row 1 of the column that has data and paste it into the table's next row (1st column). Then, copy the data from the cell that has data and paste that into the 2nd column.
Basically, if there is data, the first row of a table will come from column C of the row that has data, the next row's first column will come from Row 1 of the column that has data, and the 2nd column of the second row will come from the cell that has data within that same column.
Thank you for offering to help. Here's a hyperlink to a sample Excel file, and the very Amateurish code I've started to write within MS Word that only covers the first product:
Excel Sample File
Private Sub useVBinWord()
Dim workBook As workBook
Dim dataInExcel As String
Application.ScreenUpdating = False
Selection.TypeText Text:="Comments:"
Selection.TypeParagraph
Selection.TypeText Text:="Printed: " & Now
Selection.TypeParagraph
Set workBook = Workbooks.Open("C:\Users....xls", True, True)
ActiveDocument.Tables.Add Range:=Selection.Range, NumRows:=100, NumColumns:=2, DefaultTableBehavior:=wdWord9TableBehavior, AutoFitBehavior:=wdAutoFitFixed
With Selection.Tables(1)
If .Style <> "Table Grid" Then
.Style = "Table Grid"
End If
.ApplyStyleHeadingRows = True
.ApplyStyleLastRow = False
.ApplyStyleFirstColumn = True
.ApplyStyleLastColumn = False
.ApplyStyleRowBands = True
.ApplyStyleColumnBands = False
End With
dataInExcel = workBook.Worksheets("Top30 Comments").Range("C6").Formula
ActiveDocument.Tables(1).Cell(1, 1).Select
Selection.TypeText Text:=dataInExcel
dataInExcel = workBook.Worksheets("Top30 Comments").Range("D1").Formula
ActiveDocument.Tables(1).Cell(2, 1).Select
Selection.TypeText Text:=dataInExcel
dataInExcel = workBook.Worksheets("Top30 Comments").Range("D6").Formula
ActiveDocument.Tables(1).Cell(2, 2).Select
Selection.TypeText Text:=dataInExcel
dataInExcel = workBook.Worksheets("Top30 Comments").Range("E1").Formula
ActiveDocument.Tables(1).Cell(3, 1).Select
Selection.TypeText Text:=dataInExcel
dataInExcel = workBook.Worksheets("Top30 Comments").Range("E6").Formula
ActiveDocument.Tables(1).Cell(3, 2).Select
Selection.TypeText Text:=dataInExcel
dataInExcel = workBook.Worksheets("Top30 Comments").Range("F1").Formula
ActiveDocument.Tables(1).Cell(4, 1).Select
Selection.TypeText Text:=dataInExcel
dataInExcel = workBook.Worksheets("Top30 Comments").Range("F6").Formula
ActiveDocument.Tables(1).Cell(4, 2).Select
Selection.TypeText Text:=dataInExcel
dataInExcel = workBook.Worksheets("Top30 Comments").Range("G1").Formula
ActiveDocument.Tables(1).Cell(5, 1).Select
Selection.TypeText Text:=dataInExcel
dataInExcel = workBook.Worksheets("Top30 Comments").Range("G6").Formula
ActiveDocument.Tables(1).Cell(5, 2).Select
Selection.TypeText Text:=dataInExcel
dataInExcel = workBook.Worksheets("Top30 Comments").Range("H1").Formula
ActiveDocument.Tables(1).Cell(6, 1).Select
Selection.TypeText Text:=dataInExcel
dataInExcel = workBook.Worksheets("Top30 Comments").Range("H6").Formula
ActiveDocument.Tables(1).Cell(6, 2).Select
Selection.TypeText Text:=dataInExcel
dataInExcel = workBook.Worksheets("Top30 Comments").Range("I1").Formula
ActiveDocument.Tables(1).Cell(7, 1).Select
Selection.TypeText Text:=dataInExcel
dataInExcel = workBook.Worksheets("Top30 Comments").Range("I6").Formula
ActiveDocument.Tables(1).Cell(7, 2).Select
Selection.TypeText Text:=dataInExcel
dataInExcel = workBook.Worksheets("Top30 Comments").Range("J1").Formula
ActiveDocument.Tables(1).Cell(8, 1).Select
Selection.TypeText Text:=dataInExcel
dataInExcel = workBook.Worksheets("Top30 Comments").Range("J6").Formula
ActiveDocument.Tables(1).Cell(8, 2).Select
Selection.TypeText Text:=dataInExcel
dataInExcel = workBook.Worksheets("Top30 Comments").Range("K1").Formula
ActiveDocument.Tables(1).Cell(9, 1).Select
Selection.TypeText Text:=dataInExcel
dataInExcel = workBook.Worksheets("Top30 Comments").Range("K6").Formula
ActiveDocument.Tables(1).Cell(9, 2).Select
Selection.TypeText Text:=dataInExcel
dataInExcel = workBook.Worksheets("Top30 Comments").Range("L1").Formula
ActiveDocument.Tables(1).Cell(10, 1).Select
Selection.TypeText Text:=dataInExcel
dataInExcel = workBook.Worksheets("Top30 Comments").Range("L6").Formula
ActiveDocument.Tables(1).Cell(10, 2).Select
Selection.TypeText Text:=dataInExcel
dataInExcel = workBook.Worksheets("Top30 Comments").Range("M1").Formula
ActiveDocument.Tables(1).Cell(11, 1).Select
Selection.TypeText Text:=dataInExcel
dataInExcel = workBook.Worksheets("Top30 Comments").Range("M6").Formula
ActiveDocument.Tables(1).Cell(11, 2).Select
Selection.TypeText Text:=dataInExcel
workBook.Close True
Set workBook = Nothing
Application.ScreenUpdating = True
End Sub

You've picked a difficult project to start with! Here's my almost complete solution :
Sub ImportTable()
Dim AppExcel As Excel.Application ' link to Excel
Dim ExcelRange As Excel.Range ' range in worksheet to process
Dim ExcelData As Variant ' worksheet data as VBA array
Dim ExcelHeadings As Variant ' worksheet headings as VBA array
Dim FoundCol As Boolean ' a column found with data ***
Dim exCol As Integer ' Excel column (iterator)
Dim exRow As Integer ' Excel row (iterator)
Dim wdRow As Integer ' Word table row
' reference to open instance of Excel
Set AppExcel = GetObject(class:="Excel.Application")
' change this to create an instance and open the file
Set ExcelRange = AppExcel.ActiveSheet.UsedRange ' the spreadsheet data as a range
' change this to ensure we have the correct worksheet
' the following reads cells C6 to End into a VBA array (row,column)
ExcelData = ExcelRange.Offset(5, 2).Resize(ExcelRange.Rows.Count - 6, _
ExcelRange.Columns.Count - 2)
' the following reads the heading row starting at C1
ExcelHeadings = ExcelRange.Offset(0, 2).Rows(1)
' assumes we have a blank document in word
With ActiveDocument.Range
.InsertAfter "Comments:" & vbCrLf ' insert your document header
.InsertAfter "Printed: " & Now & vbCrLf & vbCrLf
End With
Selection.EndOf wdStory ' reposition selection at end
ActiveDocument.Tables.Add Selection.Range, 1, 2 ' create a 1 x 2 table
With ActiveDocument.Tables(1) ' use this table
.Style = "Table Grid" ' set the style (copied from your code)
.ApplyStyleHeadingRows = True
.ApplyStyleLastRow = False
.ApplyStyleFirstColumn = True
.ApplyStyleLastColumn = False
.ApplyStyleRowBands = True
.ApplyStyleColumnBands = False
' the first row is left blank for you to insert a title
' perhaps you should make this row repeat on each page
wdRow = 2 ' we will fill from row 2 which doesn't exist yet
For exRow = 1 To UBound(ExcelData, 1) Step 3 ' process every 3rd row
FoundCol = False ' mark 'not found' ***
For exCol = 2 To UBound(ExcelData, 2) ' test each column from D
If Trim(ExcelData(exRow, exCol)) <> "" Then ' if cell not empty
If Not FoundCol Then ' first filled column, write header
.Rows.Add ' add row for header
.Rows.Add ' add row for data (avoid problem with merged row)
.Rows(wdRow).Cells.Merge ' merge header row
.Rows(wdRow).Range.InsertAfter ExcelData(exRow, 1) ' add title from C
' this keeps the two rows together across page breaks
.Rows(wdRow).Range.ParagraphFormat.KeepWithNext = True
wdRow = wdRow + 1 ' row added
FoundCol = True ' header written
Else
.Rows.Add ' add row for data
' this keeps the two rows together across page breaks
.Rows(wdRow - 1).Range.ParagraphFormat.KeepWithNext = True
End If
' write heading from row 1
.Cell(wdRow, 1).Range.InsertAfter ExcelHeadings(1, exCol)
' write found data
.Cell(wdRow, 2).Range.InsertAfter ExcelData(exRow, exCol)
wdRow = wdRow + 1 ' row added
End If
Next exCol
Next exRow
End With
' don't forget to close the instance of Excel
End Sub
Read the comments, I've left you a bit of work to do!

Related

Copy Range to new workbook - Not copying, error 9

I am receiving a Run-time error '9':
Subscript out of range.
The error occurs at the end.. I am trying to open a new spreadsheet, copy edited information into it, and then I will use a script following this to dump 8-12 more files based on selection INTO 'FName' ... which may or may not work.
This is highlighted when I click debug:
Workbooks("TFR7").Sheets("Sheet1").Range("A2:V" & LastRow).Copy Destination:=Workbooks(FName).Sheets("Sheet1").Range("A1")
I do not understand the error here? Is it my range selection to copy over?
Side note: I AM working to learn how to remove the instances of select, etc. FYI
Code is below:
Sub OpenReportThenEdit()
'This will open a designated report and edit it
'File pathway and name must be correct
'Any adjustments to file layout could 'break' macro
'First file will always be TFR7 and from there can go into more
'Currently only works for TFR7
Application.ScreenUpdating = False
Dim wb As Excel.Workbook
Dim LastRow As Long
Dim FName As String
'Open a report, delete header/footer rows
Set wb = Workbooks.Open("C:\Users\USER\Downloads\TFR7", False, False)
wb.Sheets(1).Rows("1:5").EntireRow.Delete
wb.Sheets(1).Range("A" & Rows.Count).End(xlUp).EntireRow.Delete
wb.Sheets(1).Range("A" & Rows.Count).End(xlUp).EntireRow.Delete
wb.Sheets(1).Range("J" & Rows.Count).End(xlUp).EntireRow.Delete
'Edit Sheet Font/Size
With Worksheets("Sheet1").Cells.Font
.Name = "Arial"
.Size = 9
End With
'Edit Sheet Alignment, etc.
With Worksheets("Sheet1").Cells
.WrapText = False
.Orientation = 0
.AddIndent = False
.IndentLevel = 0
.ShrinkToFit = False
.ReadingOrder = xlContext
.MergeCells = False
.HorizontalAlignment = xlRight
.VerticalAlignment = xlBottom
.WrapText = False
End With
'Replace 'text to columns' and convert dates to Excel Date Value before
'Paste Values' to remove formula
Columns("L:O").Select
Selection.Insert Shift:=xlToRight, CopyOrigin:=xlFormatFromLeftOrAbove
Range("L2").FormulaR1C1 = "=DATEVALUE(LEFT(RC[4],10))"
Range("L2").Copy Destination:=Range("L2:O2")
LastRow = Cells(Cells.Rows.Count, "A").End(xlUp).Row
Range("L2:O" & LastRow).FillDown
Range("P1:S1").Copy Destination:=Range("L1:O1")
Columns("L:O").Select
Application.CutCopyMode = False
Selection.Copy
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Application.CutCopyMode = False
Selection.NumberFormat = "m/d/yyyy"
'Delete old date columns, remove duplicate values (by tracking numbers)
Columns("P:S").Select
Selection.Delete Shift:=xlToLeft
ActiveSheet.Range("A1:V" & LastRow).RemoveDuplicates Columns:=19, Header:= _
xlYes
'Select cells with values, turn them blue (because silly people want them blue)
LastRow = Cells(Cells.Rows.Count, "A").End(xlUp).Row
ActiveSheet.Range("A2:V" & LastRow).Select
With Selection.Interior
.Pattern = xlSolid
.PatternColorIndex = xlAutomatic
.ThemeColor = xlThemeColorAccent1
.TintAndShade = 0.399975585192419
.PatternTintAndShade = 0
End With
'Open Workbook, set Workbook as Destination for
FName = "C:\Users\USER\Downloads\Daily_" & _
Format(Date, "mmdd") & ".xlsm"
Workbooks.Add.SaveAs Filename:=FName, _
FileFormat:=xlOpenXMLWorkbookMacroEnabled
Workbooks("TFR7").Sheets("Sheet1").Range("A2:V" & LastRow).Copy Destination:= _
Workbooks(FName).Sheets("Sheet1").Range("A1")
Application.ScreenUpdating = True
End Sub
Work with objects instead:
Dim otherWB As Excel.Workbook
'// other code here
Set otherWB = Workbooks.Add
otherWB.SaveAs Filename:=FName, FileFormat:=xlOpenXMLWorkbookMacroEnabled
'// wb is already set to original workbook, otherWB is set to new workook
wb.Sheets("Sheet1").Range("A2:V" & LastRow).Copy Destination:=otherWB.Sheets("Sheet1").Range("A1")

VBA Loop through strings

I have to loop through a serious of variables to filter the contents of a dataset to paste it to other sheets. The code I have to paste the data is as follows
Sheets("Source").Select
LastRow = ActiveSheet.Range("A1").Offset(ActiveSheet.Rows.Count - 1, 0).End(xlUp).Row
If ActiveSheet.AutoFilterMode = False Then ActiveSheet.AutoFilterMode = True 'Enable Filters if not exists
ActiveSheet.Range("$A$3:$AY$" & LastRow).AutoFilter Field:=4, Criteria1:= _
"SelectionABC"
Range("A3:AY" & LastRow).Copy
Sheets("DestinationX").Select
Range("A4").Select
ActiveSheet.Paste
The source is always the same, but the "SelectionABC" and the "DestinationX" will change. The selection and detonation are paired, so "SelectionABC" goes to sheet "Destination1", "SelectionDEF" goes to sheet "Destination2",...
How can I loop through the selection & destination so that I don't have the repeat the code for each data transfer?
Here is a quick untested code to help you get going.
Dim i, j As Long
Dim alpha As String
Dim b As Boolean : b = False
j = 1
'~~> UPPERCASE ALPHABETIC CHARACTERS IN THE
'~~> ASCII TABLE GO FROM 65="A" TO 91="Z"
For i = 65 To 91
If i = 89 Then '~~> BECAUSE WE ARE LEFT WITH LAST TWO LETTERS "YZ"
alpha = Chr(i) & Chr(i + 1)
b = True '~~> TO COME OUT OF LOOP AFTER "YZ"
Else
alpha = Chr(i) & Chr(i + 1) & Chr(i + 2)
i = i + 2
End If
Sheets("Source").Select
LastRow = ActiveSheet.Range("A1").Offset(ActiveSheet.Rows.Count - 1, 0).End(xlUp).Row
If ActiveSheet.AutoFilterMode = False Then ActiveSheet.AutoFilterMode = True 'Enable Filters if not exists
ActiveSheet.Range("$A$3:$AY$" & LastRow).AutoFilter Field:=4, Criteria1:= _
"Selection" & alpha '~~> ADDED alpha here
Range("A3:AY" & LastRow).Copy
Sheets("Destination" & j).Select '~~> ADDED j HERE
Range("A4").Select
ActiveSheet.Paste
j = j + 1
If b Then Exit For '~~> TO COME OUT OF LOOP AFTER "YZ"
Next

Increase number of column and write into selected cell

Good day,
I need help with a little problem. I have a macro which compares cell with range of cells. If the equal cell is not found, it will add the cell at the end of the range. My problem is with equal cell. If it finds it, I need to add 3 to column index and write "X" into this cell.
I have solution for unequal cell but i dont know how to increase column index and write into the cell.
I have this so far:
Sub Compare()
Dim i As Integer
'Comparing cell is from another workbook
Selection.Copy
Windows("zzz.xlsm").Activate
Range("A2").Select
ActiveSheet.Paste
i = 2
Do While Cells(i, 3).Value <> ""
Set FirstRange = Range("C" & i)
If FirstRange.Value = Cells(2, 1).Value Then
MsgBox "Found"
Exit Do
End If
i = i + 1
Loop
If MsgBox = True Then
'Missing code
Else
Range("A2").Select
Selection.Copy
ActiveSheet.Range("E" & Rows.Count).End(xlUp).Offset(1).Select
ActiveSheet.Paste
End If
End Sub
I will appreciate any advice. Thank you for your time.
Sub Compare()
Dim i As Integer
'Comparing cell is from another workbook
Selection.Copy
Windows("zzz.xlsm").Activate
Range("A2").Select
ActiveSheet.Paste
i = 2
Do While Cells(i, 3).Value <> ""
Set FirstRange = Range("C" & i)
If FirstRange.Value = Cells(2, 1).Value Then
MsgBox "Found"
Exit Do
End If
i = i + 1
Loop
If MsgBox = True Then
Cells(i, 6) = "X" 'used to be Missing code
Else
Range("A2").Select
Selection.Copy
ActiveSheet.Range("E" & Rows.Count).End(xlUp).Offset(1).Select
ActiveSheet.Paste
End If
End Sub

How to use pastespecial with End(xlUp)

I am currently having an issue getting the data from one sheet to paste special into another sheet, I am trying to consolidate multiple files (same headers, differing number of rows) into one master sheet containing all the rows. At the moment I'm doing that by opening all the files, pulling in the tabs I want, copy and pasting the data, and then deleting the tabs. Yes I am sure there is an easier way, but I'm very new to VBA and am learning on the fly..here's what I have so far:
Sub ConsolidateSheets()
' open each file in folder
Dim Folder As String
Dim Files As String
Folder = "C:\Users\212411103\Documents\Risk Project Tracker\Risk Project Tracker Monthly\Monthly Data"
Files = Dir(Folder & "\*.xls")
Do While Files <> ""
Workbooks.Open Filename:=Folder & "\" & Files
Files = Dir
Loop
' pull in Risk Project Tracker tab from each file to new workbook
Dim wkb As Workbook
Dim sWksName As String
sWksName = "Risk Project Tracker"
For Each wkb In Workbooks
If wkb.Name <> ThisWorkbook.Name Then
wkb.Worksheets(sWksName).Copy _
Before:=ThisWorkbook.Sheets(1)
End If
Next
Set wkb = Nothing
Dim J As Integer
' add new sheet for combined data
On Error Resume Next
Sheets(1).Select
Worksheets.Add
Sheets(1).Name = "New Month"
' paste headers from first two rows into new sheet "New Month"
Sheets(2).Select
Range("A1:AH2").Select
Selection.Copy
Sheets("New Month").Select
Selection.PasteSpecial Paste:=xlPasteColumnWidths, Operation:=xlNone, _
SkipBlanks:=False, Transpose:=False
ActiveSheet.Paste
Range("A1").Select
' work through sheets
For J = 2 To Sheets.Count ' from sheet 2 to last sheet
Sheets(J).Activate ' make the sheet active
Rows("1:2").Select
Selection.Delete Shift:=xlUp
Range("A1:AH500").Select
Selection.Copy
Sheets("New Month").Select
Selection.PasteSpecial Paste:=xlPasteColumnWidths, Operation:=xlNone, _
SkipBlanks:=False, Transpose:=False
Range("A1").Select
Next
' Delete tabs that are no longer needed i.e. the tabs from the 17 files
' For Each ws in Sheets
' Application.DisplayAlerts=False
' If ws.Name <> "New Month" Then ws.delete
' Next
' Application.DisplayAlerts=True
End Sub
It appears that the primary reason you are specifying the Range .PasteSpecial method is the carry-over of column widths which is done for every tab. Perhaps cycling through A:AH once and setting the column widths should be sufficient.
Sub ConsolidateSheets2()
Dim fldr As String, fn As String, sWksName As String, sNewWksName As String
Dim ws As Worksheet, wkb As Workbook
On Error GoTo bm_Safe_Exit
Application.ScreenUpdating = False
Application.EnableEvents = False
sWksName = "Risk Project Tracker"
fldr = "C:\Users\212411103\Documents\Risk Project Tracker\Risk Project Tracker Monthly\Monthly Data"
fn = Dir(fldr & "\*.xls")
sNewWksName = "New Month"
With ThisWorkbook
Do While fn <> ""
Set wkb = Workbooks.Open(Filename:=fldr & Chr(92) & fn)
If IsObject(wkb.Worksheets(sWksName)) Then
wkb.Worksheets(sWksName).Copy _
Before:=ThisWorkbook.Sheets(1 - CBool(Sheets(1).Name = sNewWksName))
On Error GoTo bm_Need_New_Month_ws
With .Worksheets(sNewWksName)
On Error GoTo bm_Safe_Exit
.Parent.Sheets(2).Range("A3:AH502").Copy _
Destination:=.Cells(Rows.Count, 1).End(xlUp).Offset(1, 0)
End With
End If
wkb.Close False
fn = Dir
Loop
Application.DisplayAlerts = False
Do While Sheet.Count > 1: Sheets(2).Delete: Loop
End With
GoTo bm_Safe_Exit
bm_Need_New_Month_ws:
If Err.Number = 9 Then
With ThisWorkbook.Worksheets.Add(Before:=ThisWorkbook.Sheets(1))
.Name = sNewWksName
.Move Before:=Sheets(1)
.Parent.Sheets(2).Range("A1:AH2").Copy _
Destination:=.Range("A1")
For c = .Columns("AH:AH").Column To 1 Step -1
.Columns(c).ColumnWidth = _
.Parent.Sheets(2).Columns(c).ColumnWidth
Next c
End With
Resume
End If
bm_Safe_Exit:
Application.ScreenUpdating = True
Application.EnableEvents = True
End Sub

Copy data from multiple rows only if data exists

I have a spreadsheet named Data Sheet that collects data from other worksheets via formulas and works perfectly. I need a macro that will copy the data from multiple rows so I can paste into a separate workbook.
I have 30 rows of data ranging from A3:EI3 to A32:EI32. This data is collected from 1 to 30 other sheets if they are made visible and data entered. Here is the tricky part: I only want to collect the data from the visible sheets.
Here is an example of the flow I am looking for: Sheet 1 is always visible and never is hidden. Sheet 2, Sheet 3, and Sheet 4 are visible, but Sheet 5 through Sheet 30 are still hidden. Data Sheet has already collected the data from the visible sheets, but the remaining rows (Sheets 5-30) all show 0 in the data cells.
I now want to run a macro that will copy the data (to the clipboard) from Data Sheet Row 3 (represents Sheet 1), Row 4 (represents Sheet 2), etc. and allow me to paste into the next available row in another workbook.
Here is the code that works for a single row of data.
VBA Code:
Sub CopyDataSheet()
'
' CopyDataSheet Macro
'
Application.ScreenUpdating = False
Sheets("Data Sheet").Visible = True
Sheets("Data Sheet").Select
Rows("3:3").Select
Selection.Copy
Rows("1:1").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Range("E1:EF1").Select
Application.CutCopyMode = False
Selection.NumberFormat = "0"
Rows("1:1").Select
Range("B1").Activate
Selection.Copy
Sheets("Sheet 1").Select
Range("a38").Select
Sheets("Data Sheet").Visible = True
Application.ScreenUpdating = True
MsgBox "YOU HAVE CAPTURED ALL ENTERED DATA..." & _
vbCrLf & vbCrLf & "CLICK OK" _
& vbCrLf & vbCrLf & "PASTE INTO NEXT EMPTY LINE OF DATA SHEET", _
vbInformation, ""
End Sub
I'm not 100% sure what it is you are trying to do, but I think I can supply a few code fragments that may help you.
This will cycle through the sheets in an active workbook and allow you to do something based on whether or not the sheet is visible:
j = ActiveWorkbook.Sheets.Count
For i = 1 To j
Select Case Sheets(i).Visible
Case xlSheetVisible
'Do something if the sheet is visible
Case Else
'Do something when the sheet is not visible
End Select
Next i
To get the next available row there are many different ways. One of the easiest is simply this:
next_row = Range("A" &
Rows.Count).End(xlUp).row + 1
This assumes that column A will always have a value in any data rows. If this is not the case you may want to try this:
next_row = ActiveSheet.UsedRange.Rows.Count + 1
Neither is bullet proof, but it should at least give you a start.
Option Explicit
Public Sub CollectData()
Dim wsCrnt As Excel.Worksheet
Dim wsDest As Excel.Worksheet
Dim lRowCrnt As Long
Dim lRowDest As Long
On Error GoTo Err_Hnd
ToggleInterface False
Set wsDest = ThisWorkbook.Worksheets("Data Sheet")
lRowDest = wsDest.UsedRange.Rows.Count + 1&
For Each wsCrnt In ThisWorkbook.Worksheets
If wsCrnt.Visible = xlSheetVisible Then
If Not wsCrnt Is wsDest Then
For lRowCrnt = 1& To 30&
If Excel.WorksheetFunction.CountA(wsCrnt.Rows(lRowCrnt)) Then
wsCrnt.Rows(lRowCrnt).Copy
wsDest.Rows(lRowDest).PasteSpecial xlPasteValues
lRowDest = lRowDest + 1
End If
Next
End If
End If
Next
Exit_Proc:
On Error Resume Next
ToggleInterface True
Exit Sub
Err_Hnd:
MsgBox Err.Description, vbCritical Or vbMsgBoxHelpButton, _
"Error: " & Err.Number, Err.HelpFile, Err.HelpContext
Resume Exit_Proc
End Sub
Private Sub ToggleInterface(ByVal interfaceOn As Boolean)
With Excel.Application
.Cursor = IIf(interfaceOn, xlDefault, xlWait)
.StatusBar = IIf(interfaceOn, False, "Working...")
.EnableEvents = interfaceOn
.Calculation = IIf(interfaceOn, xlCalculationAutomatic, xlCalculationManual)
.ScreenUpdating = interfaceOn
.EnableCancelKey = Abs(interfaceOn)
End With
End Sub