【问题标题】:How store a range from excel into a Range variable?如何将excel中的范围存储到范围变量中?
【发布时间】:2023-03-19 00:00:02
【问题描述】:

我正在使用 VBA 读取一些 excel 单元格。

Function getData(currentWorksheet as Worksheet, dataStartRow as Integer, _
dataEndRow as Integer, DataStartCol as Integer, dataEndCol as Integer)

    Dim dataTable as Range
    dataTable = currentWorksheet.Range(currentWorksheet.Cells(dataStartRow, _
    dataStartCol), currentWorksheet.Cells(dataEndRow, dataEndCol))

    getData = dataTable

EndFunction

它抛出一个错误,对象变量或未设置块变量。如何在变量中取这个范围?请指导我。

【问题讨论】:

    标签: vba excel


    【解决方案1】:

    当您使用Range 对象时,您不能简单地使用以下语法:

    Dim myRange as Range
    myRange = Range("A1")  
    

    您必须使用 set 关键字来分配 Range 对象:

    Function getData(currentWorksheet As Worksheet, dataStartRow As Integer, dataEndRow As Integer, DataStartCol As Integer, dataEndCol As Integer)
    
        Dim dataTable As Range
        Set dataTable = currentWorksheet.Range(currentWorksheet.Cells(dataStartRow, DataStartCol), currentWorksheet.Cells(dataEndRow, dataEndCol))
    
        Set getData = dataTable
    
    End Function
    
    Sub main()
        Dim test As Range
    
        Set test = getData(ActiveSheet, 1, 3, 2, 5)
        test.select
    
    End Sub
    

    请注意,每次声明范围时,我都会使用 Set 关键字。


    您也可以允许您的 getData 函数返回 Range 对象而不是 Variant,尽管这与您遇到的问题无关。

    【讨论】:

      【解决方案2】:

      currentWorksheet 是什么?如果你使用内置的ActiveSheet,它就可以工作。

      dataStartRow=1
      dataStartCol=1
      dataEndRow=4
      dataEndCol=4
      Set currentWorksheet=ActiveSheet
      dataTable = currentWorksheet.Range(currentWorksheet.Cells(dataStartRow, dataStartCol), currentWorksheet.Cells(dataEndRow, dataEndCol))
      

      【讨论】:

      • currentWorksheet 作为增补器传递给语句所在的函数。这是Sheet2。尽管我说 Set currentWorksheet - ActiveSheet,但它仍然抛出相同的错误
      • @PriyankThakkar 请更新您的问题以显示 complete 上下文。因为我发布的代码确实有效(我测试过)。
      • @Andrew Leach - 该代码在 dataTable 分配前没有 Set 的情况下工作?
      【解决方案3】:

      定义什么是 GetData。目前还没有定义。

      Function getData(currentWorksheet as Worksheet, dataStartRow as Integer, dataEndRow as Integer, DataStartCol as Integer, dataEndCol as Integer) as variant
      

      【讨论】:

        【解决方案4】:

        将您的 dim 声明为变体,并像从数组中一样提取数据。即

        Dim y As Variant
        y = Range("A1:B2")
        

        现在你的 excel 范围都是 1 个变量(数组),y

        要提取数据,请调用“A1:B2”范围内的数组位置或任何您选择的位置。例如:

        Msgbox y(1, 1)
        

        这将返回“A1:B2”范围内的左上角框。

        【讨论】:

          【解决方案5】:

          这是一个示例,它允许在所需区域的每一行上执行代码(从选择的顶部和底部选择,或者从选择中选择

          Sub doROWSb()           'WORKS    for do selected rows     SEE FIX ROWS ABOVE  (small ver)
          Dim E7 As String    'note:  workcell E7 shows:  BG381
          E7 = RANGE("E7")    'see eg below
          Dim r As Long       'NOTE: this example has a paste formula(s) down a column(s).  WILL REDUCE 10 HOUR DAYS OF PASTING COLUMNS, DOWN TO 3 MINUTES?
          Dim c As Long
          Dim rCell As RANGE
          'Dim LastRow As Long
          r = ActiveCell.row
          c = ActiveCell.Column   'might not matter if your code affects whole line anyways, still leave as is
          
          Dim FirstRow As Long    'not in use, Delete if only want last row, note: this code already allows for selection as start
          Dim LastRow As Long
          
          
          If 1 Then     'if you are unable to delete rows not needed, just change 2 lines from: If 1, to if 0 (to go from selection last row, to all rows down from selection)
          With Selection
              'FirstRow = .Rows(1).row                 'not used here, Delete if only want last row
              LastRow = .Rows(.Rows.Count).row        'find last row in selection
          End With
          application.CutCopyMode = False             'if not doing any paste op below
          Else
              LastRow = Cells(Rows.Count, 1).End(xlUp).row  'find last row used in sheet
          End If
          application.EnableEvents = True             'EVENTS  need this?
          application.ScreenUpdating = False          'offset-cells(row, col)
          'RANGE(E7).Select  'TOP ROW SELECT
          RANGE("A1") = vbNullString                  'simple macros on-off switch, vb not here:  If RANGE("A1").Value > 0 Then
          
          
          For Each rCell In RANGE(Cells(r, c), Cells(LastRow, c)) 'new
              rCell.Select    'make 3 macros for each paste macro below
          'your code here:
          
          If 1 Then     'to if 0, if want to paste formulas/formats/all down a column
              Selection.EntireRow.Calculate     'calcs all selected rows, even if just selecting 1 cell in each row (might only be doing 1 row aat here, as part of loop)
          Else
          'dorows() DO ROWS()
          'eg's for paste cells down a column, can make 3 separate macros for each: sub alte() altf & altp
                Selection.PasteSpecial Paste:=xlPasteFormulas, Operation:=xlNone, SkipBlanks:=False, Transpose:=False    'make sub alte ()    add thisworkbook:  application.OnKey "%{e}", "alte"
                'Selection.PasteSpecial Paste:=xlPasteFormats, Operation:=xlNone, SkipBlanks:=False, Transpose:=False     'make sub altf ()    add thisworkbook:  application.OnKey "%{f}", "altf"
                'Selection.PasteSpecial Paste:=xlPasteAll, Operation:=xlNone, SkipBlanks:=False, Transpose:=False         'amke sub altp ()    add thisworkbook:  application.OnKey "%{p}", "altp"
          End If
          Next rCell
          
          'application.CutCopyMode = False            'finished - stop copy mode
          'RANGE("A2").Select
          goBEEPS (2), (0.25)       'beeps secs
          application.EnableEvents = True             'EVENTS
          
          'note:  workcell E7 has: SUBSTITUTE(SUBSTITUTE(CELL("address",$BG$369),"$",""),"","")
          'other col eg (shows: BG:BG):  =SUBSTITUTE(SUBSTITUTE(CELL("address",$BG2),"$",""),ROW(),"")&":"& SUBSTITUTE(SUBSTITUTE(CELL("address",$BG2),"$",""),ROW(),"")
          End Sub
          
          
          'OTHER:
          Sub goBEEPSx(b As Long, t As Double)   'beeps secs as:  goBEEPS (2), (0.25)  OR:  goBEEPS(2, 0.25)
            Dim dt  'as double    'worked wo as double
            Dim x
            For b = b To 1 Step -1
              Beep
              x = Timer
            Do
            DoEvents
            dt = Timer - x
            If dt < 0 Then dt = dt + 86400    '86400 no. seconds in a day, in case hit midnight & timer went down to 0
            Loop Until dt >= t
            Next
          End Sub
          

          【讨论】:

            猜你喜欢
            • 2018-03-29
            • 1970-01-01
            • 2020-02-10
            • 2015-09-28
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2014-09-28
            相关资源
            最近更新 更多