プロが教えるわが家の防犯対策術!

Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Excel.Range, Cancel As Boolean)



Cancel = True



'===============画像選択
myF = Application.GetOpenFilename _
("jpg bmp tif png gif,*.jpg;*.bmp;*.tif;*.png;*.gif", , "画像の選択", , False)
If myF = False Then
MsgBox "画像を選択してください(終了)"
Exit Sub
End If



'===============画像の掃除
For Each mySP In ActiveSheet.Shapes
myAD1 = mySP.TopLeftCell.MergeArea.Address   ←この行が黄色くなっちゃいます。
myAD2 = Target.Address
If myAD1 = myAD2 Then mySP.Delete
Next



'===============画像の貼り付け
Set mySP = ActiveSheet.Pictures.Insert(myF)



'===============タテヨコの縮尺を保持
myHH = Target.Height / mySP.Height
myWW = Target.Width / mySP.Width
If myHH > myWW Then
mySP.Height = mySP.Height * myWW
mySP.Width = Target.Width
Else
mySP.Height = Target.Height
mySP.Width = mySP.Width * myHH
End If



'===============中央へ調整
myHH2 = (Target.Height / 2) - (mySP.Height / 2)
myWW2 = (Target.Width / 2) - (mySP.Width / 2)
mySP.Top = Target.Top + myHH2
mySP.Left = Target.Left + myWW2



Set mySP = Nothing


End Sub


ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー

Private Sub Calendar1_Click()
ActiveCell.Value = Calendar1.Value
End Sub

※黄色くなってエラー表示、変数宣言がされていないとご指示いただきましたが、どうして良いのか分かりません。どのように書き加えればを教えてください。よろしくお願いいたします。

質問者からの補足コメント

  • ※シートの保護をしてから貼り付けようとするとエラーが出てしまいます。
    フォームは変えられたくないので保護は掛け、そして画像の貼り付け削除が自由にできたらと思っています。
    よろしくお願いいたします。

    No.5の回答に寄せられた補足コメントです。 補足日時:2017/11/09 10:15
  • うれしい

    ※セルを保護したところもダブルクイックで画像が貼りつきます。
    保護したセルには貼り付けられないようにすることは出来ないでしょうか。
    宜しくお願いいたします。

      補足日時:2017/11/09 16:21

A 回答 (6件)

こんにちは。



変数の使い方は、なかなか覚えられませんね。
中級までは、あってもなくてもよいと思います。
回答者でも、長くやっていても、よく分かっていない人もいるようです。
VBAというのは、あまりエラーが出ないし、予約語も少ないから、何でもありでしょうけれども、VBA関数やプロパティ名を変数に使ったりする人がいますが、それはまずいなって、分かりそうだと思うのですが。それと、私の場合は 2Byte 文字を変数には使いません。Excel等がバージョン違いが存在していたり、海外のユーティリティを使うと、文字化けが起きてしまうからです。

ただ、あえて自分なりにガンバってみたいのでしたら、例えば、myHH, myWW というのは、Double 型なのですが、こういうのの決め方というのは、ローカルモジュールで推奨型が出てきますから、それをフィードバックしてつけてあげるようにすると良いかもしれません。

>myAD1 = mySP.TopLeftCell.MergeArea.Address   ←この行が黄色くなっちゃいます。

ところで、今回のエラーって別に、変数の問題ではないのではありませんか?

>For Each mySP In ActiveSheet.Shapes
問題は、この後だと思います。Shapes というのは、オブジェクトの統合したもので、何でも入ってしまいます。プロパティがあれば、mySP.TopLeftCell でRange オブジェクトが取れるでしょうけれども、これは、オブジェクトのタイプを限定させた方が安心できます。

コードを見る限りは、Active X コントロール(Calendar)があるようです。

最近、似たような質問で、私の回答はボツになりましたが、画像の重なりの問題ですよね。画像を重ねてはならないのでしょうから、左上端のアドレス合わせだけでよいのか、工夫が必要ではないかと思います。

以下は、まだ、不具合は残っているかもしれません。

'//シートモジュール
Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Excel.Range, Cancel As Boolean)
 Dim mySP As Object
 Dim myAD1 As Range, myAD2 As Range
 Dim myF As Variant
 Dim myHH As Double, myWW As Double
 Cancel = True
 '===============画像選択
 myF = Application.GetOpenFilename _
   ("jpg bmp tif png gif,*.jpg;*.bmp;*.tif;*.png;*.gif", , "画像の選択", , False)
 If myF = False Then
  MsgBox "画像を選択してください(終了)"
  Exit Sub
 End If
 '===============画像の掃除
 For Each mySP In ActiveSheet.Shapes
  If TypeName(mySP.DrawingObject) = "Picture" Then '画像限定
   Set myAD1 = mySP.TopLeftCell   '左端上
   Set myAD2 = mySP.BottomRightCell '右端下
   If Not Intersect(Range(myAD1, myAD2), Target) Is Nothing Then mySP.Delete
  End If
 Next
 '===============画像の貼り付け
 Set mySP = ActiveSheet.Pictures.Insert(myF)

 '===============タテヨコの縮尺を保持
 myHH = Target.Height / mySP.Height
 myWW = Target.Width / mySP.Width
 If myHH > myWW Then
  mySP.Height = mySP.Height * myWW
  mySP.Width = Target.Width
 Else
  mySP.Height = Target.Height
  mySP.Width = mySP.Width * myHH
 End If
 '===============中央へ調整
 myHH2 = (Target.Height / 2) - (mySP.Height / 2)
 myWW2 = (Target.Width / 2) - (mySP.Width / 2)
 mySP.Top = Target.Top + myHH2
 mySP.Left = Target.Left + myWW2
 Set mySP = Nothing
End Sub

Private Sub Calendar1_Click()
If ActiveCell.Value = "" Then
 ActiveCell.Value = Me.Calendar1.Value
End If
End Sub
この回答への補足あり
    • good
    • 2
この回答へのお礼

有難うございます。
いろいろな方々から答えを頂き本当に感動です。

まだお願いがあるんです。
シートの保護をしてから貼り付けようとするとエラーが出てしまいます。
フォームは変えられたくないので保護は掛け、そして画像の貼り付け削除が自由にできたらと思っています。
よろしくお願いいたします。

お礼日時:2017/11/08 21:00

>シートの保護をしてから貼り付けようとするとエラーが出てしまいます。


Protect の中の、UserInterfaceOnly というプロパティをTrue にすれば、マクロはプロテクトとは関係なしに動くようになります。

'//ThisWorkbook モジュールに以下のようなプログラムを足して、再起動(または、実行)すれば、おっしゃるようになります。

Private Sub Workbook_Open()
Const PSW As String = "xyz" 'パスワード
With Worksheets("Sheet1") '保護するシート
 .Unprotect Password:=PSW
 .Protect Password:=PSW, UserInterFaceOnly:=True, DrawingObjects:=True, Contents:=True
End With
End Sub
    • good
    • 0
この回答へのお礼

早速のご回答有難うございます。
何度もお願いして申し訳ありませんが、セルを保護したところもダブルクイックで画像が貼りつきます。
保護したセルには貼り付けられないようにすることは出来ないでしょうか。
宜しくお願いいたします。

お礼日時:2017/11/09 16:20

No.3です。



>Dim 変数名をどのように、どこに書くのかも知らないでエクセルを使おうとしています。

まず基本は変数を使う前に宣言してあれば良いのですが、
特別な条件でない限り(今回の場合)なら、

Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Excel.Range, Cancel As Boolean)
Dim 変数名1
Dim 変数名2

と、最初に書くのが一般的ですかね。
    • good
    • 1
この回答へのお礼

ありがとうございます。
せっかく教えていただいているのに何のことか全く分からないのが残念です。
言われるままにコピペするだけをお許しください。
有難うございます。

お礼日時:2017/11/08 15:33

No.1です。



既存のBookはわかりませんが、チェックを外した後Excelを一旦閉じて
開いた際の新規BookにはNo.2の項目は出ず、
エラーにはならないでしょうね。

と言うより変数の宣言は最初のうちに覚える物ですから、
それを飛ばすのもどうでしょうね?

面倒でなければ

Dim 変数名

を最初に書いてしまえば良いのではないかと。
型の明確な指定は省くことになりますが、エラー表示対策にはなるのでは?
    • good
    • 1
この回答へのお礼

有難うございます。
Dim 変数名をどのように、どこに書くのかも知らないでエクセルを使おうとしています。
関数だけで使ってきて思いどりに使えないことをマクロのコピペで使えたことに味しめているだけなので
アドバイスにお答えできないのが残念です。
いろいろと有難うございます。

お礼日時:2017/11/08 14:31

先頭に


Option Explicit
がありませんか。
その行を削除すれば、変数宣言がなくてもエラーになりません。
本来は、きちんと変数を宣言してマクロを作成したほうが良いのですが、とりあえず、
Option Explicit の行を削除すれば動きます。
    • good
    • 1
この回答へのお礼

早速のアドバイスを有難うございます。
Option Explicitは有りませんでした。『変数の宣言を強制する』のチェックを外す。もしましたがエラーが出てしまいます。
操作としては文字列や数字・数式を操作して続けて画像をマクロで取りこむとエラーがでます。今は文字列などの入力をしたら保存、立ち上げて画像を貼り付けたら保存と分けて利用するとエラーがでないです。
いちいち保存・開くではめんどうですのでなんとかならないでしょうか。

お礼日時:2017/11/08 12:50

変数の宣言をしたくなければ


http://officetanaka.net/excel/vba/variable/02.htm
『変数の宣言を強制する』のチェックを外す。

今後変数の宣言をキチンとしたいなら
https://www.vba-ie.net/programing/variable-state …
こう言った所を勉強する。
    • good
    • 1
この回答へのお礼

早速のご回答をありがとうございます。
『変数の宣言を強制する』のチェックを外す。はしましたがNo.2のご回答のところでも書きましたが二度の操作をすればエラーがですにすみます。
お知恵をお貸しください。

お礼日時:2017/11/08 12:53

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

このQ&Aを見た人はこんなQ&Aも見ています