在excel中添加新列而不更改VB代码

时间:2014-10-02 10:01:01

标签: excel vba excel-vba

我创建了一个VB程序来自动更新组项目的甘特图。但现在团队想要添加一个新的列。问题是添加新列将更改我的代码并使其无法使用。可以在不更改代码的情况下添加行,但如果添加了新的列,我将不得不更新所有代码。如何在不修改VB代码的情况下添加列?

Private Sub Worksheet_Change(ByVal Target As Range)

Dim StartDate_Row As Integer
Dim Total_Weeks As Integer
Dim Date_Week_Column As Integer
Dim Number_of_Weeks As Integer
Dim Date_Week_Column_Color As Integer


StartDate_Row = 10
Date_Week_Column = 8

Range("H9:AN25").Interior.Color = xlNone

Do

For Total_Weeks = 1 To 33

   If Cells(StartDate_Row, 5).Value = Cells(8, Date_Week_Column).Value Then

    Date_Week_Column_Color = Date_Week_Column

        For Number_of_Weeks = 1 To Cells(StartDate_Row, 6).Value
            If Cells(StartDate_Row, 7).Value = 25 Then
                Cells(StartDate_Row, Date_Week_Column_Color).Interior.Color = RGB(204, 255, 299)
            End If
            If Cells(StartDate_Row, 7).Value = 50 Then
                Cells(StartDate_Row, Date_Week_Column_Color).Interior.Color = RGB(153, 255, 204)
            End If
            If Cells(StartDate_Row, 7).Value = 75 Then
                Cells(StartDate_Row, Date_Week_Column_Color).Interior.Color = RGB(102, 255, 178)
            End If
            If Cells(StartDate_Row, 7).Value = 100 Then
                Cells(StartDate_Row, Date_Week_Column_Color).Interior.Color = RGB(50, 200, 100)
            End If
            If Cells(StartDate_Row, 7).Value = 0 Then
                Cells(StartDate_Row, Date_Week_Column_Color).Interior.Color = RGB(149, 179, 215)
            End If


            Date_Week_Column_Color = Date_Week_Column_Color + 1
        Next Number_of_Weeks

    End If

    Date_Week_Column = Date_Week_Column + 1

Next Total_Weeks
Date_Week_Column = 8



StartDate_Row = StartDate_Row + 1
Loop While (Not IsEmpty(Cells(StartDate_Row, 5)))



End Sub

3 个答案:

答案 0 :(得分:1)

汤姆的建议是可能的,但对于宏的每次运行都会给用户带来很多麻烦。

可能的技巧1

我从不按数字引用列或行有两个原因:

  • 您可能会发现列和行可以移动。
  • 阅读代码的人必须知道第5列或第6行的含义。

最好使用常量。例如:

Const ColXxxx As Long = 5
Const RowYyyy As Long = 8

If Cells(StartDate_Row, ColXxxx).Value = Cells(RowYyyy, Date_Week_Column).Value Then

我不知道您的行和列是什么,所以我使用ColXxxxRowYyyy作为名称。您可以用名称替换我的名字,告诉读者行和列是什么。

这样的代码需要花费更长的时间来编写,但(1)它是自我记录的,(2)如果列或行移动,您只需要更改Const语句来解决问题。

注意:我使用的数据类型为Long。数据类型Integer定义了一个16位变量,需要在32位和64位计算机上进行特殊(慢速)处理。

可能的技巧2

技术1要求用户告诉程序员他们想要添加列或移动行。如果他们在使用修改后的工作表运行宏之前忘记告诉程序员,宏可能会损坏工作表而无法修复。

另一种技术是在第1行搜索已知的列标题并记录其中的位置。你有一个标题为“开始日期”的列。对于一次运行宏,“开始日期”可以在第5列,在第6列则可以在第5列,您的代码将正常工作。

如果这项技术很有意思,我会添加示例代码。

答案 1 :(得分:0)

简而言之,您必须更改代码。这会变得越来越大,代码变得越大越复杂。因此,尽可能尝试动态思考用于指定单元格位置的方法。

E.g。您可以在脚本中构建一个用户输入,允许用户指定包含所需信息的列。这样,如果用户向表中添加了更多列,脚本仍将正常运行(前提是用户选择了正确的列)。

'ask user to select the column containing the data which they would like to utilise

Dim colRng As Range

On Error Resume Next
    Set colRng = Application.InputBox("Select a cell from anywhere in the column which contains the programme start dates.", Default:="", Type:=8)
On Error GoTo 0

If colRng Is Nothing Then
    'notify user that the process cannot continue as selection was invalid
    MsgBox "You must select a cell to enable this process to continue!"
    'exit the sub
    Exit Sub
End If

'output the column number (as selected by the user)
debug.print colRng.column

希望有所帮助!

答案 2 :(得分:0)

如果在工作表上定义命名范围(使用Formulas > Define Name),即使插入或删除行和列,该名称也会更新为指向相同的单元格。

在您的代码中,您可以使用(例如)MySheet.[MyRangeName].Row来获取名为MyRangeName的范围的第一行的行号,依此类推。