web-dev-qa-db-ja.com

[追加/削除]ボタンExcel VBA

これがこの写真の私のプロジェクトの例です

enter image description here

集めるのが好きなので、Excelで目録シートを作っています。

ボタンをクリックして次または前のセルに影響を与える方法を作りたい

例えば:

セルC3には Add ボタン、セルD3にはそのアイテムのコピー数があり、セルE3には Subtract ボタン。 C3のボタンをクリックすると、セルD3の数値にさらに1つ追加されます。 C1のボタンをクリックすると、セルD3から減算されます。かなり簡単そうです。

ただし、条件は以下のとおりです。

私は20枚のシート(例ではありません)に1シートあたり200アイテムほど持っています。各ボタンに固有の新しいマクロを作成しなくても、すべてのボタンにマクロを追加できる方法が欲しいのですが。また、選択したセルで機能しないようにします。追加ボタンの場合は右側のセルに、減算ボタンの場合は左側のセルに影響を与える必要があります。

私はどこでも答えを探しましたが、解決策にかなり近づきました。

これは私が見つけた最も近いものですが、私が探しているものではありません:

 Sub AddOne()
 ActiveCell.Value = ActiveCell.Value + 1
 End Sub

 Sub SubtractOne()
 ActiveCell.Value = ActiveCell.Value - 1
 End Sub

これが理にかなっていると思います。

4
Corkrum

ソリューションが機能しない理由は、ユーザーがボタンをクリックしても、ワークシートのActiveCell値は変更されず、セルではなくボタンをクリックしているためです。

これに取り組む方法はいくつかあります。多数のボタンを作成し、1つの汎用サブルーチンで作業を行うか、セル変更イベントをトラップしてそれに応答することができます。 1つ目は、より優れたユーザーエクスペリエンスになりますが、最初に設定する作業が増えます。

方法1:ボタン

このメソッドは、ボタンの名前を使用して、適切なセルで適切なアクションを実行します。概要として、すべてのボタンを作成し、それぞれに同じ汎用VBAサブルーチンを呼び出します。これにより、どのボタンがそれを呼び出しているかがわかり、適切な操作が実行されます。

たとえば、D3の値を増減するために、ボタンをADD_D3SUB_D3のように呼び出すと仮定します。


まず、VBAで作業を行うためのサブルーチンを作成します。

Sub AdjustValue()
    Dim btnName As String
    Dim targetCell As String
    Dim addAmount As Integer

    btnName = Application.Caller
    targetCell = Mid(btnName, 5, Len(btnName))
    addAmount = IIf(Left(btnName, 3) = "ADD", 1, -1)

    ActiveSheet.Range(targetCell).Value = _
        ActiveSheet.Range(targetCell).Value + addAmount
End Sub

それを分解する:

  1. Application.Callerは、呼び出し元の名前、この場合はボタンの名前を提供します
  2. 最初の4文字をスキップして、ターゲットセルの名前を最後から削除します
  3. 最初の3文字に基づいて、加算するか減算するかを判断します
  4. ターゲットセル名を使用して、ワークシートセルを更新します

次に、ボタンを作成します。それぞれのスプレッドシートにフォームコントロールボタンを追加する + そして - 必要なボタン。

それぞれについて、上記のように、対象とするセルに基づいて体系的な名前を割り当てます。たとえば、上のスクリーンショットでは、最初の2つのボタンにADD_D3およびSUB_D3という名前を付けることができます。
ボタンの名前を変更するには、ボタンを右クリックして選択し、ワークシートの左上にあるアドレスボックスで、名前(例:ボタン1)を新しい名前で上書きします。
enter image description here

最後に、サブはActiveSheetを使用してセルにアクセスするため、上記は複数のシートでも機能するはずです。


方法2:選択の変更

これはセットアップがはるかに簡単ですが、少しハックです。まず、各セルにプラス記号とマイナス記号を付けてシートを設定し、色を付けますが、ボタンのように見せたい場合があります。例えば: enter image description here

記号をテキストとしてセルに入れるには、一重引用符( ')を使用する必要があることに注意してください。 '-および'+(これは、例の上部にある数式バーに表示されます)。

次に、選択されているセルの1つに応答する単一のルーチンを作成します。

Sub Worksheet_SelectionChange(ByVal Target As Range)
    Dim numCell As Range

    If Target.Count <> 1 Then Exit Sub

    If Target.Value = "+" Then
        Set numCell = Target.Offset(0, -1)
        numCell.Select
        numCell.Value = numCell.Value + 1
    ElseIf Target.Value = "-" Then
        Set numCell = Target.Offset(0, 1)
        numCell.Select
        numCell.Value = numCell.Value - 1
    End If
End Sub

それを分解する:

  1. サブルーチンの名前は重要です-ユーザーが任意のセルをクリックしたときにExcelにサブルーチンを実行するように指示します
  2. Targetパラメータは、ユーザーがクリックしたセルですが、ドラッグして選択することもできます。最初にサイズが正確に1であることを確認し、そうでない場合は終了します。
  3. 次に、その値で+または-の値を確認します。引用符をチェックする必要がないことに注意してください。
  4. 次に、Offsetコマンドを使用して、+または-のどちらの開始セルを処理しているかに応じて、左または右のセルを検索します
  5. 数値セルを取得したら、まずそれを選択し、次にその値を上下に変更します

数値セルを選択するのは、選択範囲をoff+または-セルに移動するためです。もう一度クリックします。これらのセルで作業する場合は、このサブルーチンを一時的に無効にする必要があります。たとえば、上部にExit Sub行を挿入します。

小さなメモ:Worksheet_SelectionChangeは、シートのマクロで作業している場合に使用するものです。 enter image description here

ThisWorkbookモジュールで作業している場合は、グローバル選択変更サブルーチンを使用する必要があります。

Private Sub Workbook_SheetSelectionChange(ByVal Sh As Object, ByVal Target As Range)
    'Code goes in here
End Sub

同じコードが機能するはずです。この場合、ワークブックのすべてのシートで機能します。


両方の例を示すスプレッドシートの例 here

4
Geoff