Share via

How to set the range object in Excel for VBA

Anonymous
2014-04-08T21:12:20+00:00

I am really rusty on VBA for Excel (2010).

Want to loop through all the worksheets in a workbook and copy the contents of each to a different workbook.  I've got the part down regarding working with the two workbooks.  Where I am stuck is that I think I should set a range object first before copying and am having trouble with it.

  • each worksheet has the same number of header rows so I have put this in as a constant

   e.g. StartDataCol = 1 and StartDataRow = 12 (set in the constants part of the module)

  • I figured I could use the .UsedRange() method to return what I need i.e. I only want to copy over rows that are filled
  • below bombs
  • too bad all the MSFT documentation just shows how to work with hardcoded ranges e.g. "A1:B10" etc
  • I can't figure out the syntax when working with constants or calling other functions to return a value
  • my code here loops through each worksheet

FOR EACH loCurrentWS IN  loSourceWB.Worksheets

            ' create a range starting at the start row/col of constants set at top

            Set loSourceRange = loCurrentWS.Range(StartDataCol & StartDataRow, _

               loCurrentWS.UsedRange.Columns.Count & loCurrentWS.UsedRange.Rows.Count)

          loSourceRange.Copy

        ' then the goal was to paste that into the target worksheet

next

THANKS in advance!

Albert

Microsoft 365 and Office | Excel | For home | Windows

Locked Question. This question was migrated from the Microsoft Support Community. You can vote on whether it's helpful, but you can't add comments or replies or follow the question.

0 comments No comments

Answer accepted by question author

HansV 462.6K Reputation points
2014-04-09T20:56:31+00:00

You can use

.Range("B2").Formula = "=COUNTIF(DataSheet!D12:D" & lnLastRow & ",""AW"")"

Instead of using "" to insert a double quote inside a quoted string, you can concatenate with Chr(34):

.Range("B2").Formula = "=COUNTIF(DataSheet!D12:D" & lnLastRow & "," & Chr(34) & "AW" & Chr(34) & ")"

but whether that is more readable is up to you. You cannot use a delimiter such as ' or [ ] instead of ".

Was this answer helpful?

0 comments No comments

Answer accepted by question author

HansV 462.6K Reputation points
2014-04-08T21:27:27+00:00

Try this:

            With loCurrentWS

                Set loSourceRange = .Range(.Cells(StartDataRow, StartDataCol), _

                    .Cells(.UsedRange.Rows.Count, .UsedRange.Columns.Count))

            End With

Was this answer helpful?

0 comments No comments

6 additional answers

Sort by: Most helpful
  1. Anonymous
    2014-04-09T00:45:17+00:00

    Both Hans and Ron have shown how to do it with

    Range(Cells(row,col), Cells(row,col))  

    type referencing of the range - which is fast and effecient.  These also fit right in with your (very wise move) of declaring constants for startDataRow and startDataColumn.

    If you want to use Range to build a formula that uses column letters and row numbers - those look a little more like what you attempted:

    Sub Dummy()

      Const StartCol = "A"

      Const StartRow = 12

      Const LastCol = "R" ' if you happen to know it

      Dim LastRow As Long

      Dim RangeToCopy As Range

    'assuming column A has entries for all used rows

      LastRow = Range(StartCol & Rows.Count).End(xlUp).Row

      Set RangeToCopy=Range(StartCol & StartRow & ":" & LastCol & LastRow)

    'do more stuff like copy and paste

    'good housekeeping to release resources you SET back to the system

      Set RangeToCopy = Nothing

    End Sub

    By the way, Ron de Bruin has a really nice function that you can use to determine:

    The last row used in any range (from a single column to all cells on the sheet)

    The last column used in any range (from single row to all cells on the sheet)

    And the address of the intersection of last row and last column.

    It is on this page: http://www.rondebruin.nl/win/s9/win005.htm

    The combined function is down about 3/4 of the page.

    Was this answer helpful?

    0 comments No comments
  2. Anonymous
    2014-04-09T00:39:53+00:00

    Hans,

       It probably wouldn't make a difference here, but note that your method assumes that Row 1 and subsequent are part of UsedRange.  If the first one or more rows are blank, the desired range may not be returned.

    Of course, my method may return a larger range under some circumstances, but shouldn't return a smaller range.

    Was this answer helpful?

    0 comments No comments
  3. Anonymous
    2014-04-09T00:33:26+00:00

    Many ways.

    Here's one, with variable declaration required, and using "last cell".  There are other ways to find the last used cell, however.

    Dim loCurrentWS As Worksheet

    Dim loSourceRange As Range

    Const StartDataCol As Long = 1

    Const StartDataRow As Long = 12

    'Next line only here for testing purposes

    'In your macro, it would be set as you iterate through the

    '   worksheet loop

    Set loCurrentWS = ActiveSheet

    With loCurrentWS

        Set loSourceRange = .Range(.Cells(StartDataRow, StartDataCol), .Cells.SpecialCells(xlCellTypeLastCell))

    End With

    Edit:  I note that you wrote you want to copy only the rows with data.  If the "data" is NOT a result of formulas, you could set that range a bit more robustly by looking for the last row and column with data:

    Dim loCurrentWS As Worksheet

    Dim loSourceRange As Range

    Dim lLastRow As Long, lLastCol As Long

    Const StartDataCol As Long = 1

    Const StartDataRow As Long = 12

    'Next line only here for testing purposes

    'In your macro, it would be set as you iterate through the worksheet loop

    Set loCurrentWS = ActiveSheet

    With loCurrentWS

    'cell must contain value

        lLastRow = .Cells.Find(what:="*", after:=[a1], LookIn:=xlValues, _

            searchorder:=xlByRows, searchdirection:=xlPrevious).Row

        lLastCol = .Cells.Find(what:="*", after:=[a1], LookIn:=xlValues, _

            searchorder:=xlByColumns, searchdirection:=xlPrevious).Column

        Set loSourceRange = Range(.Cells(StartDataRow, StartDataCol), .Cells(lLastRow, lLastCol))

    End With

    Was this answer helpful?

    0 comments No comments