2

私は初心者のプログラマー (経験なし) で、現在行っている仕事のために Visual Basic を学習しています。私は一日かそこら読んでいて、ついに必要なプログラムを作り始めることに決めました!

ただし、いくつかの問題が発生しています。

現在、2 つのサブルーチンがあります。最初のサブルーチンでは、ユーザーがデータ ペアの数を入力できるようにして、ユーザーが入力するテーブルを作成できるようにします。これは、ユーザーのデータが後で参照できるように適切な場所に配置されるようにするためです。

次に、データの入力が完了した後に押すボタンがあり、入力した数値に対していくつかの計算を行う別のサブルーチンを開始します。私の問題は、2 番目のルーチンに引き継がなければならないデータ ペアの数を示す変数が必要なことです。

続行する前に、これまでのコードを示します。(ウィンドウを下にスクロールする必要があります) また、2 番目のサブルーチンが別のモジュールにあることにも注意してください。

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 の値が 2 番目のサブルーチンに引き継がれないのはなぜですか? 現在、列 B に入力されたセルの数をカウントする回避策があります。これにより、数値が得られます。ただし、それにより、使用したいシートの残りの部分に列 B のスペースを使用できなくなります。

誰でも助けることができますか?「パブリック」はワークブックレベルの変数になると思いましたか? 2 番目のサブに Counter の値を表示させるたびに、0 として表示されます。

私のコードが乱雑/非効率的である場合は申し訳ありません。まだ勉強してる。:)

4

2 に答える 2

5

あなたのコードでは、Public Counter As Long2回宣言しています。おそらく起こっていることは、各Subブロックが異なるCounter変数を取得していることです。2 番目のものを削除すると、両方とも同じ変数を共有するはずです。

Option Explicitまた、モジュールごとに 1 回だけリストする必要があります。これで、これらが個別のモジュールであると指定したことがわかりましたが、うまくやっています。

編集:もっと解明しようとしています。

それを階層化と考えてください。各「スコープ」は、レイヤーがアクセスできるものです。各レイヤーは、それ自体とすべての親にアクセスできます。単純化された視覚化を次に示します。

( program 
    ( module
        ( sub )
    )
)

サブルーチンで変数を参照すると、プログラムは上向きに検索を開始します。もちろん、設定したと仮定するOption Explicitと、変数は手動で定義する必要があり、自動的に定義されることはありません。

欲しいものは以下のようなものです。同時に実行されている他のモジュールからアクセスできるように、変数はスコープ内でグローバルです。

( program
    [global variable]
    ( module1
        ( sub )
    )
    ( module2 )
)
于 2012-07-06T18:45:18.167 に答える
0

本番環境で必要になる可能性のある余分なコードを削除しましたが、問題の発生を妨げているだけです。以下をテストしましたが、Counter は、最初のモジュールの最初のサブに設定された値を 2 番目のモジュールのサブに保持します。

モジュール 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 はその値を失います。これらのいずれも発生していない場合は、ウォッチを追加して、コードのステップ実行中に変数の値を追跡する必要があります。

ウォッチを追加するには、変数を右クリックし、ウォッチの追加...を選択して、モジュールのドロップダウンから(すべてのモジュール)を選択します。式の値が変化したときにウォッチ ブレークを設定することもできます。

于 2012-07-06T20:11:25.537 に答える