Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Looking to select an undetermined number of rows in excel as part of larger VBA macro

I'm working with an excel book containing a large number of sheets; the first sheet is linked to an external program and pulls in data via an external function, and the number of lines imported varies significantly.

This block data is the disseminated over a number of subsequent sheets. The first step has been to populate column A (row name) with the number of rows in sheet 1. From here the data is split over a number of columns (currently B->L). The top row uses an IF() function to populate the first row, and I'm looking to write a clean macro to copy this formula to row x (which varies with each data import refresh) and then paste values for a manageable file size.

Here's what I've got so far; it works, but it's fairly (read: VERY!) clumsy:

Sub Refresh_Data()  
    Sheets("Sheet2").Select  
    ActiveWindow.ScrollWorkbookTabs Sheets:=13  
    Sheets(Array("Sheet2" ... "Sheet25")).Select     
    Sheets("Sheet2").Activate  
    Sheets("Sheet25").Select Replace:=False  
    Range("B1:L1").Select  
    Selection.Copy  
    Range("__B2:B1000__").Select  
    ActiveSheet.Paste  
    Application.Calculate  
    ActiveWindow.ScrollWorkbookTabs Position:=xlFirst  
    Sheets(Array("Sheet2" ... "Sheet25")).Select  
    Sheets("Sheet2").Activate  
    Sheets("Sheet25").Select Replace:=False  
    Sheets("Sheet2").Select  
    Range("B3").Select  
    Sheets(Array("Sheet2" ... "Sheet25")).Select  
    Sheets("Sheet2").Activate  
    Sheets("Sheet25").Select Replace:=False  
    Range("B3:L4").Select  
    Range("__B2:L1000__").Select  
    Application.CutCopyMode = False  
    Selection.Copy  
    Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _  
        :=False, Transpose:=False  
    Sheets("Check_sheet").Select  
    MsgBox "Update complete"  
End Sub`

The main thing I'm looking to achieve is to replace the code B2:L1000 with something that can assess the number of rows in column A and select a range in rows B to L accordingly.

Since column L is the last populated column, I don't see why this can't also be done horizontally rather than defining "B:L" incase future columns need to be added.

like image 357
heavyarms Avatar asked Dec 12 '22 07:12

heavyarms


1 Answers

Although the earlier answer has merits:

1) I would not use COUNTA because if there are empty cells in the row or column, the cells at the bottom or the right will be ignored.

2) I would never rely on the user picking the correct sheet to be used before running a macro; particularly one with so many sheets.

My reaction to the question is that you have set Macro Record, wandered around your workbook and then stopped the record. You select one thing, then another. You scroll through the sheets. To me most of the statements are not clumsy they are pointless.

The following does include an answer to your question about finding the last row of column A but it is more a tutorial about finding the dimensions of a range, getting data out of the range and then putting it somewhere else. This seems to be most of what you are trying to do with the most minimal understanding of VBA. I am sorry if this criticism is unfair but that is the impression your question gives to me.

Sub Test()

  Dim RowS01Max As Integer
  Dim Sheet1Data() As Variant

  ' With Sheets("Sheet1") allows you to access data within worksheet Sheet1
  ' without selecting it.
  ' Range("A1:C11") refers to a range within the active sheet
  ' .Range("A1:C11") refers to a range within the sheet identified in the
  '         With statement.
  ' ^ Note the dot
  With Sheets("Sheet1")

    ' Rows.Count is the number of rows for the version of Excel you are using.
    ' .Cells(Rows.Count, "A") address the bottom row of column A of worksheet
    ' Sheet1.
    ' .Cells(Rows.Count, 1) refer to column A by number.
    ' End(xlUp) is the VBA equivalent of Ctrl+Up.
    ' If you positioned the cursor at the bottom of column A and pressed
    ' Ctrl+Up, the cursor would jump to the last row in column A with a value.
    ' The following statement gets that row number without actually moving
    ' the cursor.
    RowS01Max = .Cells(Rows.Count, "A").End(xlUp)

    ' The following statement loads the contents of range A1:C11 of
    ' Sheets("Sheet1") into array Sheet1Data.
    Sheet1Data = .Range("A1:C11").Value

    ' This is the same statement but the range is specified in a different way.
    ' .Cells(Row,Column) identifies a single cell within the sheet specified in
    ' the With statement.  .Cells(1,1) identifies row 1, column 1 which is A1.
    '. Cells(11, "C") identifies row 11, column C which is C11.
    Sheet1Data = .Range(.Cells(1, 1), .Cells(11, "C")).Value

    ' This statement uses RowS01Max to specify the last row
    Sheet1Data = .Range(.Cells(1, 1), .Cells(RowS01Max, 1)).Value

    ' In all three examples above, the contents of the specified range will
    ' be loaded to array Sheet1Data.  Whichever range you pick, Sheet1Data
    ' will always be a two dimensional array with the first dimension being
    ' the row and the second dimension being the column.

    ' In the first two examples Sheet1Data(5,3) contains the contents
    ' of cell C5.  In the third example, I have only loaded column A but the
    ' array will still has two dimensions but the only permitted value for the
    ' second dimension is 1.

    ' The following statement writes the contents of Sheet1Data to column "E"

    .Range(.Cells(1, 5), .Cells(RowS01Max, 5)).Value = Sheet1Data

  End With

  With Sheets("Sheet2")

    ' The following statement writes the contents of Sheet1Data to column "E"
    ' of worksheet Sheet2.
    .Range(.Cells(1, 5), .Cells(RowS01Max, 5)).Value = Sheet1Data

  End With

End Sub

Don't despair! Most of us started with the macro recorder and still use it to discover the syntax for an unfamiliar command. Look through other questions. Some ask about exotic functionality but many are about moving data around in, to the experienced programmer, simple ways. Set up some workbooks with the questioner's problem. Copy and paste the solution into a module. Step through it using F8 (see the debugger), switch between Excel and Editor, watch what is happening to the worksheet and move the cursor over a variable to see its current value. Spend half a day playing. You will be amazed at how quickly it starts to make sense. Good luck and good programming.

like image 91
Tony Dallimore Avatar answered Apr 30 '23 20:04

Tony Dallimore