電子書籍の厳選無料作品が豊富!

エクセル マクロ セルの値が変わった時、自動でマクロを実行させたいです。

以前、こちらで教えていただいたコードで下のような表を作りました。
‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥
■ボタンを押すと画像が配置される表

【Sheet1】…商品在庫一覧表(テキスト情報&商品画像のパス)
【Sheet2】…
 1、Sheet1から必要なデータだけを関数で呼び出しておく
 2、印刷用の体裁として6行目以下に並び替え(テキスト情報は‘=’で自動配置)、
   「画像を配置」ボタンをトリガーにして画像を配置
   (※D列の画像のパスを行7に(あ→い))
 3、「リセット」ボタンで画像を削除
‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥
社内でとても便利に使っておりましたが
「毎回ボタンを押すのが面倒くさい」という意見があり、
自動で配置できないかと思っています。

やりたいこと
※A1~D3列が変わった時点で(ボタンを押さずに)6行目以下に画像を表示させたい
※「リセット」ボタンを押さなくても、次の更新があった時点で古い画像が削除され
 新しい画像が配置されるようにしたい
‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥

■現在の構文(教えていただいたものをほぼそのまま貼り付けています。すみません)

Private Sub photo_1() '←「画像を表示」ボタン(★)

Const n As Long = 2 'margin
Dim r As Range 'Loop用
Dim tr As Range '読み込みセル用
Dim s As String 'セル文字列
Dim X As Double '縦横比固定での縮小率
Dim i As Long

With Sheets("【Sheet2】")

For Each r In .Range("D1", "D3")
s = r.Value
If Len(s) = 0 Then Exit For
i = i + 1
If Len(Dir(s)) > 0 Then
Set tr = .Cells(7, i)
With .Pictures.Insert(s).ShapeRange
.LockAspectRatio = msoTrue
X = Application.Min((tr.Width - n) / .Width, (tr.Height - n) / .Height)
.Width = .Width * X
.Left = tr.Left + (tr.Width - .Width) / 2
.Top = tr.Top + (tr.Height - .Height) / 2
End With
End If
Next

(-略-)

End With '念のためファイルを解放
Dir Application.Path

Set tr = Nothing
End Sub



Private Sub photo_2() '←「リセット」ボタン(★)
Sheets("【Sheet2】").Pictures.Delete
End Sub

‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥
(★)の部分をなくして自動化したいです。
「Worksheet_Calculate(Change?)」というのでできるらしい…
と知って色々やってみましたが、うまくいきません。

お時間がありましたら教えてください。
どうぞよろしくお願いいたします。

「エクセル マクロ セルの値が変わった時、」の質問画像

A 回答 (4件)

無限ループとはループ処理(繰り返し処理)を行う際


出口が無い状態で永遠にここから抜け出せない状態を言います
これはコードのミスの場合が多いですね
これに入ってしまった場合はEscキーで抜けることができます

今回あなたが提示したコードでは
For Each~のループ処理がありますが
ループする範囲が明確に決まっていますので
無限にはなりません 

他のプログラムを呼び出して実行するような
プログラム構造にする有利な点は 見やすくなるのと
エラーを起きたときの修正がわかりやすくなる、
(機械製品なんかでも悪い箇所のユニットを交換する対応がありますよね)
プロシージャ(コードの一単位)を使いまわしできる

などのメリットがあります 
要するにメンテナンスがしやすくなるのです
ただ、この場合注意すべき点があります
変数などに格納した値が他のプロシージャに移ったときに反映されない問題です
これを回避するには
 変数の有効範囲を広げる(Public変数など)、サブルーチンに値を引数で渡す
などがあります このあたりは本を読んだほうがいいですね

個人的にお勧めする本は 大村あつし氏のかんたんプログラミングExcelVBAですね
これは基本、応用、コントロールの3冊ありますが
3冊とも買ったほうがいいですよ 本気で覚えたいと思うなら必須かと・・

まぁ ワタシもまだまだ知ったかぶりの初心者の域です
    • good
    • 1
この回答へのお礼

ご回答ありがとうございます。

>ループする範囲が明確に決まっていますので
>無限にはなりません

これだけでも教えていただけて本当に助かりました。
やみくもにループについて調べていたので…。

また、ご親切にお勧めの本まで教えていただき、大変うれしいです。
早速、3冊まとめて注文しました。
今まで何度か覚えようとしてその度に挫折していました。
ですが、今回はちょっとがんばってみます。

sumer45様、
色々と大事なことを教えていただき、とても助かりました。
どうもありがとうございました。

お礼日時:2010/06/11 15:06

追伸:



もともと、コマンドボタンで動作してるのだから
希望するイベントのときにそれを呼び出せばいいだけの事

ちなみに Call は省略しても動作するが
呼び出していることがわかりやすいので入れておいたほうがいいと思う
(個人の好み)

この回答への補足

sumer45様

ご回答ありがとうございます。

>もともと、コマンドボタンで動作してるのだから
>希望するイベントのときにそれを呼び出せばいい

なるほど、こんなことは思いつきもしませんでした。すごいです。
教えていただいた通りやってみて、はじめはうまくいかないな、と困っていたのですが
たまたま100枚ぐらいの画像を配置するように設定してテストしていたところ
重かったためか、一瞬だーっと画像が配置されているのが見えました(そして消えました)。

これが「無限ループ」というものなのでしょうか。。
どこかで止める方法を読んだことがある気がするので、自分なりに調べてみたいと思います。
ここまで教えていただいてとても助かりました。
どうしても解決できないようでしたら、もう一度お尋ねすることがあるかもしれません。
その時はまた教えていただけたらうれしいです。

取り急ぎお礼申し上げます。

補足日時:2010/06/11 11:15
    • good
    • 1

元のコードは標準モジュールにおき、


Private Sub・・ を Sub・・・ にする

でもって 提示したコードは対象となるシートのイベントなので
そのシートモジュールに置く
    • good
    • 1

Private Sub Worksheet_Change(ByVal Target As Range)



If Intersect(Target, Range("希望セル範囲")) Is Nothing Then Exit Sub
Cancel = True

Call photo_1
Call photo_2

End If

End Sub

こういう事?

この回答への補足

早速のご回答ありがとうございます。


分かりにくい説明でしたが、添付した「説明画像」は現在の状況で、

・「画像を表示」ボタン(←これを押さないと画像が表示されない)
・「リセット」ボタン(←画像を削除するボタン)

上の2つのボタンなしで、グレーの部分(【Sheet2】のA1~D3)の更新に合わせて画像を自動表示させたいのです。
説明不足ですみません。

教えていただいたコードを書き足してみましたがうまくいきませんでした(知識不足が原因かもしれません)。
何かお気づきの点がありましたら教えていただけると助かります

補足日時:2010/06/10 16:51
    • good
    • 1

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!