如何为下一个子程序保留此变量的值?

时间:2012-07-06 18:22:57

标签: excel vba excel-vba scope

我是一名初学程序员(没有经验)学习Visual Basic来完成我现在正在做的工作。我已经读了一天左右,最后决定开始制作所需的程序!

但是,我遇到了一些问题。

现在我有两个子程序。第一个子程序允许用户输入他们有多少数据对,这样我就可以创建一个表来填写。这样他们的数据就在我以后的正确位置。

然后他们在完成输入数据后按下一个按钮以启动另一个子程序,该子程序将对他们输入的数字进行一些计算。我的问题是我需要一个变量来说明他们必须将多少数据对转移到第二个例程。

在继续之前,这是我的代码到目前为止! (你必须在窗口中向下滚动)我还应该注意第二个子程序在一个单独的模块中。

Option Explicit

Public Counter As Long


Sub TableCreation1()

    ActiveSheet.Shapes.Range(Array("Button 5")).Select

    Selection.Delete

    Counter = InputBox("How many pairs of data do you have? ")

    Range("A1") = "Time (days)"

    Range("B1") = "CFL (measured)"

    Range("A1:B1").Font.Bold = True

    Columns("A:B").EntireColumn.EntireColumn.AutoFit

    Range("A1").Select

    ActiveCell.Range("A1:B" & Counter + 1).Select

    Selection.Borders(xlDiagonalDown).LineStyle = xlNone

    Selection.Borders(xlDiagonalUp).LineStyle = xlNone

    With Selection.Borders(xlEdgeLeft)

       .LineStyle = xlContinuous

       .Weight = xlThin

    End With

    With Selection.Borders(xlEdgeTop)

        .LineStyle = xlContinuous

        .Weight = xlThin

    End With

    With Selection.Borders(xlEdgeBottom)

        .LineStyle = xlContinuous

        .Weight = xlThin

    End With

    With Selection.Borders(xlEdgeRight)

        .LineStyle = xlContinuous

        .Weight = xlThin

    End With

    With Selection.Borders(xlInsideVertical)

        .LineStyle = xlContinuous

        .Weight = xlThin

    End With

    With Selection.Borders(xlInsideHorizontal)

        .LineStyle = xlContinuous

        .Weight = xlThin

    End With

    Dim btn As Button

    Dim rng As Range

    With Worksheets("Sheet1")

        Set rng = .Range("A" & Counter + 2)

        Set btn = .Buttons.Add(rng.Left, rng.Top, rng.Width, rng.Height)

    With btn

        .Caption = "Click this button to begin calculations"

        .AutoSize = True

    End With

    End With

End Sub



Option Explicit

Dim IntermediateVariable As Long

Public Counter As Long

Sub FindCFLGuess()

IntermediateVariable = Worksheets("Sheet1").Range("B:B").Cells.SpecialCells(xlCellTypeConstants).Count

Counter = IntermediateVariable - 1

End Sub

为什么Counter不能将值转移到第二个子程序?现在我有一个解决方法,计算B列中填写的单元格数量,这给了我数字。但是,这使得我无法将B列中的任何空间用于我想要使用的其余表格。

有人可以帮忙吗?我认为“公共”会使它成为一个工作簿级变量?每当我使第二个子显示计数器的值时,它就会变为零。

很抱歉,如果我的代码混乱/效率低下。我还在学习。 :)

2 个答案:

答案 0 :(得分:5)

在您的代码中,您声明Public Counter As Long两次。可能会发生的是,您的每个Sub块都会获得不同的Counter变量。如果你删除第二个,他们都应该共享相同的变量。

此外,您应该只需要为每个模块列出Option Explicit一次。现在,我看到你指定这些是单独的模块,你做得很好。

编辑:试图澄清更多信息。

将其视为分层,每个“范围”是图层可以访问的内容。每个层都可以访问自己和所有父母。这是一个简化的可视化:

( program 
    ( module
        ( sub )
    )
)

在子程序中引用变量,程序开始向上查找。假设您当然设置了Option Explicit,这意味着必须手动定义变量,并且永远不会自动定义它们。

您想拥有的是以下内容。变量在范围内是全局的,以便可以从同时运行的其他模块访问它。

( program
    [global variable]
    ( module1
        ( sub )
    )
    ( module2 )
)

答案 1 :(得分:0)

我删除了一堆您在生产中可能需要的无关代码,但这只会妨碍您查看问题。我测试了以下内容,并且Counter将其在第一个模块中的第一个子集中设置的值保持到第二个模块中的sub。

第1单元:

Option Explicit

    Public Counter As Long

    Sub TableCreation1()
        Dim btn As Button
        Dim rng As Range

        Counter = InputBox("How many pairs of data do you have? ")
        Range("A1") = "Time (days)"
        Range("B1") = "CFL (measured)"
        Range("A1:B1").Font.Bold = True
        Columns("A:B").EntireColumn.EntireColumn.AutoFit
        Range("A1").Select
        ActiveCell.Range("A1:B" & Counter + 1).Select

        With Worksheets("Sheet1")
            Set rng = .Range("A" & Counter + 2)
            Set btn = .Buttons.Add(rng.Left, rng.Top, rng.Width, rng.Height)
            With btn
                .Caption = "Click this button to begin calculations"
                .AutoSize = True
            End With
        End With
    End Sub

第2单元:

Option Explicit

Sub FindCFLGuess()
    MsgBox ("Counter = " & Counter)
End Sub

如果您创建一个包含2个模块的新工作簿并将代码粘贴到每个模块中,那么如果依次运行messagebox然后TableCreation1,则计数器变量的值将显示在FindCFLGuess

如果由于某种原因出现运行时错误,或者中断了代码的执行,显然Counter会失去其值。如果这些都没有发生,你应该添加一块手表 在单步执行代码时跟踪变量的值。

要添加监视,请右键单击该变量,选择添加监视... ,然后从模块下拉列表中选择(所有模块)。当表达式的值发生变化时,您也可以使用watch break。