0

我想知道是否有人可以帮助我。

我将下面的代码放在一起,在我的工作簿中创建一个新工作表并应用动态命名范围和页面格式。

Sub AllDataNamedRanges()

Dim rLOB As Range
Dim rStaffName As Range
Dim rTask As Range
Dim rProjectName As Range
Dim rProjectID As Range
Dim rJobRole As Range
Dim rMonth As Range
Dim rActuals As Range

Set rLOB = Range([B4], [B4].End(xlDown))
Set rStaffName = Range([C4], [C4].End(xlDown))
Set rTask = Range([D4], [D4].End(xlDown))
Set rProjectName = Range([E4], [E4].End(xlDown))
Set rProjectID = Range([F4], [F4].End(xlDown))
Set rJobRole = Range([G4], [G4].End(xlDown))
Set rMonth = Range([H4], [H4].End(xlDown))
Set rActuals = Range([I4], [I4].End(xlDown))

Sheets("AllData").Select

    ActiveWorkbook.Names.Add Name:="LOB", RefersToR1C1:="=" & _
    ActiveSheet.Name & "!" & rLOB.Address(ReferenceStyle:=xlR1C1)

    ActiveWorkbook.Names.Add Name:="StaffName", RefersToR1C1:="=" & _
    ActiveSheet.Name & "!" & rStaffName.Address(ReferenceStyle:=xlR1C1)

    ActiveWorkbook.Names.Add Name:="Task", RefersToR1C1:="=" & _
    ActiveSheet.Name & "!" & rTask.Address(ReferenceStyle:=xlR1C1)

    ActiveWorkbook.Names.Add Name:="ProjectName", RefersToR1C1:="=" & _
    ActiveSheet.Name & "!" & rProjectName.Address(ReferenceStyle:=xlR1C1)

    ActiveWorkbook.Names.Add Name:="ProjectID", RefersToR1C1:="=" & _
    ActiveSheet.Name & "!" & rProjectID.Address(ReferenceStyle:=xlR1C1)

    ActiveWorkbook.Names.Add Name:="JobRole", RefersToR1C1:="=" & _
    ActiveSheet.Name & "!" & rJobRole.Address(ReferenceStyle:=xlR1C1)

    ActiveWorkbook.Names.Add Name:="Month", RefersToR1C1:="=" & _
    ActiveSheet.Name & "!" & rMonth.Address(ReferenceStyle:=xlR1C1)

    ActiveWorkbook.Names.Add Name:="Actuals", RefersToR1C1:="=" & _
    ActiveSheet.Name & "!" & rActuals.Address(ReferenceStyle:=xlR1C1)

End Sub

该代码确实有效,但我有点担心它可能有点笨拙并且可以写得更聪明。我对 VBA 比较陌生,但我愿意学习。

我只是想知道是否有人,也许比我更有经验的程序员,可以看看这个,并提供一些指导,告诉我如何才能把它写得更好一点。

非常感谢和亲切的问候

4

2 回答 2

1

最好的方法是根本不通过代码来完成,而是使用动态命名范围,这将在您添加新数据时更改范围。

下面的命名范围公式设置了一个动态的命名范围覆盖范围Sheet1!$A$4:$A$1000

=OFFSET(Sheet1!$A$4,0,0,COUNTA(Sheet1!$A$4:$A$1000),1)
  1. 公式/名称管理器
  2. 新的
  3. 输入名称、范围和引用上面的公式(注释是可选的)
  4. 好的

在此处输入图像描述

您也可以使用整个 A:A 列,但如果您从 A4 开始计数,则需要调整 A1:A3 中具有值的单元格的数量。在图片示例中,它将是

=OFFSET(Sheet1!$A$4,0,0,COUNTA(Sheet1!$A:$A)-1,1)
于 2013-08-10T18:10:25.327 回答
0

我同意 ooo 的回答:如果您可以使用 Excel 的功能而不是 VBA 的话。但是,我必须反对:

Set rLOB = Range([B4], [B4].End(xlDown))

End(xlDown)没有定义我假设你想要的最后使用的行。如果单元格 B4 为空白且其下方没有已使用的单元格,则将 rLOB 设置为 B4 直到列的底部。如果单元格 B4 为空白并且 B4 下方有已使用的单元格,则将 rLOB 设置为 B4 直到第一个非空白单元格。如果 B4 是非空白的,它将 rLOB 从 B4 设置到下一个空白单元之前的单元。

如果有空白单元格,每列的范围将下降到不同的行。

查找最后使用的行或列(如果这是您的话)可能会很棘手,因为没有任何方法可以在每种情况下为您提供正确的结果。

创建一个空工作簿,将下面的代码放在一个模块中并运行宏。它显示了一系列技术和每种技术的问题。希望这可以帮助。

Option Explicit
Sub FindFinal()

  Dim Col As Long
  Dim Rng As Range
   Dim Row As Long

  ' Try the various techniques on an empty worksheet
  Debug.Print "***** Empty worksheet"
  Debug.Print ""

  With Worksheets("Sheet1")

    .Cells.EntireRow.Delete

    Set Rng = .UsedRange
    If Rng Is Nothing Then
      Debug.Print "Used range is Nothing"
    Else
      Debug.Print "Top row of used range is: " & Rng.Row
       Debug.Print "Left column row of used range is: " & Rng.Column
      Debug.Print "Number of rows in used range is: " & Rng.Rows.Count
      Debug.Print "Number of columns in used range is: " & Rng.Columns.Count
       Debug.Print "!!! Notice that the worksheet is empty but the user range is not."
    End If

    Debug.Print ""

    Set Rng = .Cells.Find("*", .Range("A1"), xlFormulas, , xlByRows, xlPrevious)
     If Rng Is Nothing Then
      Debug.Print "According to Find the worksheet is empty"
    Else
      Debug.Print "According to Find the last row containing a value is: " & Rng.Row
    End If

    Debug.Print ""
    Set Rng = .Cells.SpecialCells(xlCellTypeLastCell)
    If Rng Is Nothing Then
      Debug.Print "According to SpecialCells the worksheet is empty"
    Else
      Debug.Print "According to SpecialCells the last row is: " & Rng.Row
       Debug.Print "According to SpecialCells the last column is: " & Rng.Column
    End If

    Debug.Print ""
    Row = .Cells(1, 1).End(xlDown).Row
    Debug.Print "Down from A1 goes to: A" & Row
     Row = .Cells(Rows.Count, 1).End(xlUp).Row
    Debug.Print "up from A" & Rows.Count & " goes to: A" & Row
    Col = .Cells(1, 1).End(xlToRight).Column
    Debug.Print "Right from A1 goes to: " & ColNumToCode(Col) & "1"
     Col = .Cells(1, Columns.Count).End(xlToLeft).Column
    Debug.Print "Left from " & Columns.Count & _
                "1 goes to: " & ColNumToCode(Col) & "1"

    ' Add some values and formatting to worksheet

    .Range("A1").Value = "A1"
    .Range("A2").Value = "A2"
    For Row = 5 To 7
      .Cells(Row, "A").Value = "A" & Row
     Next
    For Row = 12 To 15
      .Cells(Row, 1).Value = "A" & Row
    Next

    .Range("B1").Value = "B1"
    .Range("C2").Value = "C2"
    .Range("B16").Value = "B6"
     .Range("C17").Value = "C17"

    .Columns("F").ColumnWidth = 5
    .Cells(18, 4).Interior.Color = RGB(128, 128, 255)
    .Rows(19).RowHeight = 5

    Debug.Print ""
     Debug.Print "***** Non-empty worksheet"
    Debug.Print ""

    Set Rng = .UsedRange
    If Rng Is Nothing Then
      Debug.Print "Used range is Nothing"
    Else
      Debug.Print "Top row of used range is: " & Rng.Row
       Debug.Print "Left column row of used range is: " & Rng.Column
      Debug.Print "Number of rows in used range is: " & Rng.Rows.Count
      Debug.Print "Number of columns in used range is: " & Rng.Columns.Count
       Debug.Print "!!! Notice that row 19 which is empty but has had its height changed is ""used""."
      Debug.Print "!!! Notice that column 5 which is empty but has had its width changed is not ""used""."
       Debug.Print "!!! Notice that column 4 which is empty but contains a coloured cell is ""used""."
    End If

    Debug.Print ""

    Set Rng = .Cells.Find("*", .Range("A1"), xlFormulas, , xlByRows, xlPrevious)
     If Rng Is Nothing Then
      Debug.Print "According to Find the worksheet is empty"
    Else
      Debug.Print "According to Find the last row containing a formula is: " & Rng.Row
    End If
     ' *** Note: search by columns not search by rows ***
    Set Rng = .Cells.Find("*", .Range("A1"), xlFormulas, , xlByColumns, xlPrevious)
    If Rng Is Nothing Then
      Debug.Print "According to Find the worksheet is empty"
     Else
      Debug.Print "According to Find the last column containing a formula is: " & Rng.Column
    End If
    ' *** Note: Find returns a single cell and the nature of the search
    '           affects what it find.  Compare SpecialCells below.

    Debug.Print ""
    Set Rng = .Cells.SpecialCells(xlCellTypeLastCell)
    If Rng Is Nothing Then
      Debug.Print "According to SpecialCells the worksheet is empty"
    Else
      Debug.Print "According to SpecialCells the last row is: " & Rng.Row
       Debug.Print "According to SpecialCells the last column is: " & Rng.Column
    End If

    Debug.Print ""
    Row = 1
    Do While True
      Debug.Print "Down from A" & Row & " goes to: ";
       Row = .Cells(Row, 1).End(xlDown).Row
      Debug.Print "A" & Row
      If Row = Rows.Count Then Exit Do
    Loop

  End With

  With Worksheets("Sheet2")

    .Cells.EntireRow.Delete

  .Range("B2").Value = "B2"
  .Range("C3").Value = "C3"
  .Range("B7").Value = "B7"
  .Range("B7:B8").Merge
   .Range("F3").Value = "F3"
  .Range("F3:G3").Merge

    Debug.Print ""
    Debug.Print "***** Try with merged cells"

    Set Rng = .UsedRange
     If Rng Is Nothing Then
      Debug.Print "Used range is Nothing"
    Else
      Debug.Print "Used range is: " & Replace(Rng.Address, "$", "")
    End If

     Debug.Print ""
    Set Rng = .Cells.Find("*", .Range("A1"), xlFormulas, , xlByRows, xlPrevious)
    If Rng Is Nothing Then
      Debug.Print "According to Find the worksheet is empty"
     Else
      Debug.Print "According to Find the last cell by row is: " & Replace(Rng.Address, "$", "")
    End If
    Set Rng = .Cells.Find("*", .Range("A1"), xlFormulas, , xlByColumns, xlPrevious)
     If Rng Is Nothing Then
      Debug.Print "According to Find the worksheet is empty"
    Else
      Debug.Print "According to Find the last cell by column is: " & Replace(Rng.Address, "$", "")
     End If
      Debug.Print "!!! Notice that Find can ""see"" B7 but not F3."

    Debug.Print ""
    Set Rng = .Cells.SpecialCells(xlCellTypeLastCell)
    If Rng Is Nothing Then
       Debug.Print "According to SpecialCells the worksheet is empty"
    Else
      Debug.Print "According to SpecialCells the last row is: " & Rng.Row
      Debug.Print "According to SpecialCells the last column is: " & Rng.Column
     End If

  End With

End Sub
Function ColNumToCode(ByVal ColNum As Long) As String

  Dim Code As String
  Dim PartNum As Long

  ' Last updated 3 Feb 12.  Adapted to handle three character codes.
   If ColNum = 0 Then
    ColNumToCode = "0"
  Else
    Code = ""
    Do While ColNum > 0
      PartNum = (ColNum - 1) Mod 26
      Code = Chr(65 + PartNum) & Code
      ColNum = (ColNum - PartNum - 1) \ 26
     Loop
  End If

End Function
于 2013-08-13T23:18:36.143 回答