我想知道是否有人可以帮助我。
我将下面的代码放在一起,在我的工作簿中创建一个新工作表,并应用动态命名范围和页面格式。
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比较陌生,但我愿意学习。
我只是想知道某个人,或许比我更有经验的程序员,是否可以看一下这个,并提供一些关于如何能够更好地写这个的指导。
非常感谢和亲切的问候
答案 0 :(得分:1)
最好的方法是不要通过代码完成,而是使用动态命名范围,这会在您添加新数据时更改范围。
以下命名范围公式设置动态命名范围,涵盖范围Sheet1!$A$4:$A$1000
=OFFSET(Sheet1!$A$4,0,0,COUNTA(Sheet1!$A$4:$A$1000),1)
您也可以使用整个列A:A,但如果从A4开始计数,则需要调整A1:A3中值的单元格数。在图片示例中,它将是
=OFFSET(Sheet1!$A$4,0,0,COUNTA(Sheet1!$A:$A)-1,1)
答案 1 :(得分:0)
我同意ooo的回答:如果你可以使用Excel的力量代替VBA呢。但是,我必须反对:
Set rLOB = Range([B4], [B4].End(xlDown))
End(xlDown)
没有定义我认为你想要的最后一行。如果单元格B4为空白且其下方没有使用过的单元格,则将rLOB设置为B4,直到列的底部。如果单元格B4是空白的并且使用了低于B4的单元格,则将rLOB设置为B4直到第一个非空白单元格。如果B4是非空白的,它会将B4中的rLOB设置为下一个空白单元格之前的单元格。
如果有空白单元格,则每列的范围将下移到不同的行。
查找上次使用的行或列,如果这就是你的话,可能会很棘手,没有任何方法可以在每种情况下为你提供正确的结果。
创建一个空的工作簿,将下面的代码放在一个模块中并运行宏。它显示了各种技术和问题。希望这会有所帮助。
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