Excel (VBA)

Excel VBAに関するフォーラムです。
  • 解決済みのトピックにはコメントできません。
このトピックは解決済みです。
質問

 
(指定なし : Excel 2013)
各セルの値ごとにオートシェイプの表示と非表示
投稿日時: 17/06/14 17:10:27
投稿者: Kdos

VBA初心者で 挑戦しては毎回挫折しています。
関数でなんとか凌げていたのですが、さすがにVBAでないとダメな状況に追い詰められ、詰んでしまいました。
 
 
用途として、データベースシートから参照した情報を印刷用シート(固定様式)のセルの文字を囲むようにオートシェイプを表示させたいといった内容です。
 
様々なサイト参照し、オートシェイプを場所やサイズを指定して作成するよりも、あらかじめ設置してあるオートシェイプに名前を付け透明化、参照セルで結果で、可視化をVBAですれば出来ると考え以下の様な物をつくりました。
 
 
▼VBA印刷用シートに記述
 

Sub Worksheet_Change(ByVal Target As Range)

If Target.Address <> "C1" Then Exit Sub
If Target.Value = "●" Then
   
   '### 製品A項目に●があったらオートシェイプを表示
   ActiveSheet.Shapes("製品A").Visible = True

   '### 製品A項目に●がなかったらオートシェイプを非表示(透明化)
Else
   ActiveSheet.Shapes("製品A").Visible = False
End If
Exit Sub
End Sub

 
データベースシートからVLOOKUPでセルC1に表示させ、その結果を参照し●であったら、オートシェイプ(製品A)を表示 その他だったらオートシェイプを非表示といった具合で動かしてます。
別途、VLOOKUPの再計算を別マクロでボタン化してます。(ここは問題ない)
一応、これで動くことを確認していますが、製品項目がほかにも多数あり、続けて記述すると、コンパイルエラーになってしまい、2つ目以降のオートシェイプがうまく動作出来ません。
 
Sub Worksheet_Change(ByVal Target As Range)
If Target.Address <> "C2" Then Exit Sub
If Target.Value = "●" Then
   
   '### 製品B項目に●があったらオートシェイプを表示
   ActiveSheet.Shapes("製品B").Visible = True

   '### 製品B項目に●がなかったらオートシェイプを非表示(透明化)
Else
   ActiveSheet.Shapes("製品B").Visible = False
End If
Exit Sub
End Sub

 
以上のようにセルC2が製品B、セルC3が製品C・・・といった感じで10項目ほどあり追加していけば、処理が続けて出来ると思ってたのですが、ご教授頂ければ幸いです。
 

回答
投稿日時: 17/06/14 22:26:10
投稿者: simple

突っ込みどころがいくつかあります。
ヒントだけ書きます。
 
1. Sheetモジュールには Changeイベントプロシージャは一つしか書けません。
   ひとつのプロシージャのなかで、
      もし、 ○○なら
          こうする
      もし、 △△なら
          ああする
   という形に書きます。
 
2. C1セルの計算結果の変動はchangeプロシージャを起動させません。
 
3. Target.Addressの結果は絶対参照形式ですから、相対参照形式では判定できません。
 
少なくとも、上記3点を検討してみて下さい。

回答
投稿日時: 17/06/15 16:02:28
投稿者: mattuwan44

特定のセルの選択(変更)が特定の図形と連動しているなら、
こういった流れで処理したらいいと思います。
 
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
    Dim sName As String
    Dim flg As Boolean
     
    'イベント処理したいセル範囲(C1からC4)以外マクロ処理中止
    If Intersect(Target, Me.Range("C1:C4")) Is Nothing Then Exit Sub
    '対象が複数セルの場合マクロ処理中止(複数セルを操作してしまった時はどうしたい?)
    If Target.CountLarge > 1 Then Exit Sub
     
    '対象セルの行番号で条件分岐し、製品名を取得
    Select Case Target.Row
        Case 1: sName = "製品A"
        Case 2: sName = "製品B"
        Case 3: sName = "製品C"
        Case 4: sName = "製品D"
    End Select
   '表示非表示のフラグを取得
    If Target.Value = "●" Then flg = True
 
    '選択した図形の表示状態を変更
    Me.Shapes(sName).Visible = flg
End Sub

回答
投稿日時: 17/06/15 16:08:24
投稿者: mattuwan44

>VBA初心者で 挑戦しては毎回挫折しています
 
たぶん、1個1個の細かい作業手順に分解して表現するのが苦手なのかなと思います。
 
やりたいことを実現するための手順を、
1手1手分解して、日本語で箇条書きするところから始めてみてはいかがでしょうか?
日本語からVBAへの翻訳は回答者が手伝ってくれますが、
やりたいことを上手く表現できなければ、なかなかお手伝いするのは難しいかなと思います。
 

投稿日時: 17/06/16 21:18:18
投稿者: Kdos

simple様
mattuwan44様
 
ご回答本当にありがとうございます。
BASIC言語の基礎が出来ていないのが問題ですね。
まあ、エクセルの関数が出来るぐらいの素人が独学でVBAをやろうとするのが間違いなわけで・・・
 
そもそも単純なコードでって出来るわけがないですよね。
設計から作り直してみます。