Excel VBA質問箱 IV

当質問箱は、有志のボランティア精神のおかげで成り立っています。
問題が解決したら、必ずお礼をしましょうね。
本サイトの基本方針をまとめました。こちら をご一読ください。

投稿種別の選択が必要です。ご注意ください。
迷惑投稿防止のため、URLの入力を制限しています。ご了承ください。


1887 / 13645 ツリー ←次へ | 前へ→

【71205】写真を指定して貼り付ける ようちゃん 12/2/9(木) 15:50 質問[未読]
【71207】Re:写真を指定して貼り付ける kanabun 12/2/9(木) 19:05 発言[未読]
【71212】Re:写真を指定して貼り付ける ようちゃん 12/2/10(金) 15:56 回答[未読]
【71214】Re:写真を指定して貼り付ける kanabun 12/2/10(金) 18:55 発言[未読]
【71208】Re:写真を指定して貼り付ける kanabun 12/2/9(木) 20:12 発言[未読]
【71210】Re:写真を指定して貼り付ける UO3 12/2/9(木) 20:38 発言[未読]
【71215】Re:写真を指定して貼り付ける ようちゃん 12/2/10(金) 20:07 回答[未読]
【71216】Re:写真を指定して貼り付ける kanabun 12/2/10(金) 21:01 発言[未読]
【71217】Re:写真を指定して貼り付ける ようちゃん 12/2/10(金) 22:20 回答[未読]
【71220】Re:写真を指定して貼り付ける kanabun 12/2/11(土) 9:43 発言[未読]
【71229】Re:写真を指定して貼り付ける ようちゃん 12/2/11(土) 21:50 お礼[未読]

【71205】写真を指定して貼り付ける
質問  ようちゃん  - 12/2/9(木) 15:50 -

引用なし
パスワード
   いつも大変お世話になっております。
指定した画像をエクセルに貼り付けるプログラムを教えてください。
以下のような処理ができるマクロを作成したいと思います。
何卒よろしくお願いいたします。

1.画像が入ったデスクトップ上のフォルダをよみにいく。
' フォルダ選択画面を表示
Set shell = CreateObject("Shell.Application")
Set myPath = shell.BrowseForFolder(&O0, "フォルダを選んでください", &H1 + &H10, "D:\")
Set shell = Nothing

2.この中には、撮影した画像が大量に入っています。この中から必要な写真のみエクセルへ貼り付けたいと思います。エクセルのセルに必要な写真名(100.jpgなら100と記載)を記入して、その画像を貼り付けます。画像を記載するセル番号や、写真の貼り付け先は以下のようにしたいと思います。

写真名を記載するセル番号  写真の左上のセル番号   写真の大きさ指定  
・J3 ・・・・・・・・・・・・・J10・・・・・・・・・・・・3行〜18行
・J30・・・・・・・・・・・・・J30・・・・・・・・・・・・23行〜38行
・J50・・・・・・・・・・・・・J50・・・・・・・・・・・・43行〜58行
・J70・・・・・・・・・・・・・J70・・・・・・・・・・・・63行〜78行
・J90・・・・・・・・・・・・・J90・・・・・・・・・・・・83行〜98行

※写真の大きさ指定は、行方向へは上記のように指定しますが、A列B列など、列方向へは指定しません。縦横比は固定したいと思います。以上のようなマクロはできますでしょうか?

お手数ですが、マクロを始めたばかりで、画像をすべて貼り付けるマクロしか作成できませんでした・・。お手数ですがお力をお貸しくだされば幸いです。何卒よろしくお願いいたします。

【71207】Re:写真を指定して貼り付ける
発言  kanabun  - 12/2/9(木) 19:05 -

引用なし
パスワード
   ▼ようちゃん さん:
こんにちは〜
回答ではありません。

> 画像をすべて貼り付けるマクロしか作成できませんでした・・。
画像をすべて貼り付けるマクロができているなら、さしあたりその
マクロをここに掲載されたらいかがですか?


> 画像を記載するセル番号や、写真の貼り付け先は以下のようにしたいと思います。
>
>写真名を記載するセル番号  写真の左上のセル番号   写真の大きさ指定  
>・J3 ・・・・・・・・・・・・・J10・・・・・・・・・・・・3行〜18行
>・J30・・・・・・・・・・・・・J30・・・・・・・・・・・・23行〜38行
>・J50・・・・・・・・・・・・・J50・・・・・・・・・・・・43行〜58行
>・J70・・・・・・・・・・・・・J70・・・・・・・・・・・・63行〜78行
>・J90・・・・・・・・・・・・・J90・・・・・・・・・・・・83行〜98行
>
>※写真の大きさ指定は、行方向へは上記のように指定しますが、A列B列など、列方向へは指定しません。縦横比は固定したいと思います。

「写真の大きさ指定」にある 「3行〜18行」とかの数値の意味がよく分かりません。
「写真の左上のセル番号」が J3 で 行方向に [J3:J18] の高さにリサイズして
貼り付けたい...  とかなら、分かるんですけど?

【71208】Re:写真を指定して貼り付ける
発言  kanabun  - 12/2/9(木) 20:12 -

引用なし
パスワード
   ▼ようちゃん さん:

>指定した画像をエクセルに貼り付けるプログラム

Excelのバージョンはいくつですか?

画像の貼り付けというと
Pictures.Insert という方法と、
Shapes.AddPicture という方法とあります。

> 縦横比は固定
とのことなので、前者が妥当かと思いますが、
Excel2010 では Pictures.Insert の仕様が勝手に変更され、
この方法は ディスク上の画像にリンクする方式(ディスク上の原画像が無くなると、
シート上の画像も消える)に変わりました。
したがって、どのExcelのバージョンで処理するかにより
処理コードが変わってきます。

【71210】Re:写真を指定して貼り付ける
発言  UO3  - 12/2/9(木) 20:38 -

引用なし
パスワード
   ▼ようちゃん さん:

もし、勘違いならスルーしてください。
HNは異なりますが
www.vbalab.net/vbaqa/c-board.cgi?cmd=one;no=71185;id=excel

テーマが同じで、フォルダ指定のコードも同じで、かつ、
>画像をすべて貼り付けるマクロしか作成できませんでした・・
というところも、同じですね。
縦横比率の維持というところも同じ。

で、私から、シートレイアウトは不明でしたけど、たとえばB列に画像ファイル名が列挙されていたとしたらという想定で、コード案もアップしています。

それがうまくいかないのであれば、そちらのほうで、追加で質問していただければよろしいのに・・・
と思ったりして、いささか不愉快ですねぇ。

【71212】Re:写真を指定して貼り付ける
回答  ようちゃん  - 12/2/10(金) 15:56 -

引用なし
パスワード
   kanabun様、いつも大変お世話になっております。丁寧なご回答ありがとうございます。以下ご質問いただいた内容について、ご回答いたします。宜しくお願いします!


1.選択したセルに記載された画像ファイルパス(名)のファイルを読み込み、EXCELに貼り付ける形しか思いつきませんでした・・・。ですが本当はエクセルにファイルパスを記入せずとも画像を貼り付けられるような形にしたいと思います・・。
'
Sub EggFunc_pasteImage()
' 変数定義
Dim filePath As String
Dim targetCell As Range

' エラーを無視する(画像ファイル読込み失敗時用)
On Error Resume Next

' 選択したセル範囲を順次処理
For Each targetCell In Selection.Cells
    
' セルを選択
targetCell.Select
    
' 値があれば
If targetCell.Value <> "" Then
      
' 画像ファイル名として取得
filePath = targetCell.Value
      
' 画像読込み
ActiveSheet.Pictures.Insert(filePath).Select
      
' 画像が大きい場合、画像サイズをセル幅に合わせる

 Selection.width= targetcell.width
 Selection.Height = targetCell.Height
 End If
 End If
 End If
  
 Next

End Sub


2.「写真の大きさ指定」にある 「3行〜18行」とかの数値の意味がよく分かりません。「写真の左上のセル番号」が J3 で 行方向に [J3:J18] の高さにリサイズして貼り付けたい...  とかなら、分かるんですけど?
→おっしゃる通りです。「写真の左上のセル番号」がA10で行方向「A3:A18」の高さにリサイズして貼り付けるという意味です。(「写真左上のセル番号」はJ列ではなくA列でした。失念しておりました。すいません。)

>写真名を記載するセル番号  写真の左上のセル番号   写真の大きさ指定  
>・J3 ・・・・・・・・・・・・・A10・・・・・・・・・・・・3行〜18行
>・J30・・・・・・・・・・・・・A30・・・・・・・・・・・・23行〜38行
>・J50・・・・・・・・・・・・・A50・・・・・・・・・・・・43行〜58行
>・J70・・・・・・・・・・・・・A70・・・・・・・・・・・・63行〜78行
>・J90・・・・・・・・・・・・・A90・・・・・・・・・・・・83行〜98行
>
>※写真の大きさ指定は、行方向へは上記のように指定しますが、A列B列など、列方向へは指定しません。縦横比は固定したいと思います。

3.エクセルバージョンは、Excel2007です。

【71214】Re:写真を指定して貼り付ける
発言  kanabun  - 12/2/10(金) 18:55 -

引用なし
パスワード
   ▼ようちゃん さん:
>1.選択したセルに記載された画像ファイルパス(名)のファイルを読み込み、EXCELに貼り付ける形しか思いつきませんでした・・・。ですが本当はエクセルにファイルパスを記入せずとも画像を貼り付けられるような形にしたいと思います・・。
>
>>2.「写真の大きさ指定」にある 「3行〜18行」とかの数値の意味がよく分かりません。
>→おっしゃる通りです。「写真の左上のセル番号」がA10で行方向「A3:A18」の高さにリサイズして貼り付けるという意味です。(「写真左上のセル番号」はJ列ではなくA列でした。失念しておりました。すいません。)

>3.エクセルバージョンは、Excel2007です。

私からの質問に対するお返事、どうもありがとうございます。
けれど、UO3 さんからのコメントにはお返事いただけないのですか?

【71215】Re:写真を指定して貼り付ける
回答  ようちゃん  - 12/2/10(金) 20:07 -

引用なし
パスワード
   お返事ありがとうございます。
連絡が遅くなり申し訳ありません。

以前のレスを確認しました。
確かに私の質問内容と一緒ですね。その原因が分かりました。

私とその方は別人ですが、一緒にVBAを勉強している仲間でした。
お互い先生から同じ課題を出されているのですが、
コードがなかなかわからなかったところ、
このサイトを見つけたため、別々に質問してしまったようです。
不愉快な思いをさせてしまい、誠に申し訳ありませんでした。
私が以前のレスを事前に確認しておりましたら、
このようなことにはならなかったと反省しております。
本当に申し訳ございません。。。

【71216】Re:写真を指定して貼り付ける
発言  kanabun  - 12/2/10(金) 21:01 -

引用なし
パスワード
   ▼ようちゃん さん:
>以前のレスを確認しました。
>確かに私の質問内容と一緒ですね。その原因が分かりました。
>
>私とその方は別人ですが、一緒にVBAを勉強している仲間でした。
>お互い先生から同じ課題を出されているのですが、
>コードがなかなかわからなかったところ、
>このサイトを見つけたため、別々に質問してしまったようです。
>不愉快な思いをさせてしまい、誠に申し訳ありませんでした。
>私が以前のレスを事前に確認しておりましたら、
>このようなことにはならなかったと反省しております。
>本当に申し訳ございません。。。

以下を試してみてください。
始めに、画像のある「Folderを指定」します。これまでのコードは
C:\ となってましたが、↓ではdesktopに変更してあります。
また、BrowseForFolder のツリーにFolder名だけでなく ファイル名
までも表示することがオプションを付け加えることにより、可能に
なります。
フォルダが選択されたら、Dir関数のLoopで フォルダ内のすべての
ファイルを検索し、そのうちファイル拡張子が <.jpeg><.jpg><.gif>
のファイルだけ シートのA列に「図の挿入」をします。
Excel2003までは 貼り付け先セルをアクティブにしておけば、その位置
に貼り付くのですけど、Excel2007 なのでそうなりません。ウィンドウ
の真ん中に貼り付けてから、 .Left .Top を指定しなおして目的のセルに
移動します。
 貼り付けセルは最初 [A10]セルで、あとは 20行ずつ下に移動していき
ます。
 貼り付ける画像の「高さ方向のサイズ」は、もし元の画像がセル15行
分より大きかったら、セル15行分に縮小しています。縦横比は固定です。

貼り付け作業は 独立したプロシージャで行ってます。
画像を貼り付けたら、そのセルのF列の位置に 貼り付けた画像名 を
書き込みます(J列だと、離れていたので)。
...などなど、いろいろ、勝手に仕様を変更しています。
コードを読んで、そちらの仕様に変更してください。

Sub PasteDirImage()
 'フォルダ選択
 Dim oFolder As Object
 Const BIF_RETURNNONLYFSDIRS = &H1 'ディレクトリのみ選択可
 Const BIF_EDITBOX = &H10 'アイテム名入力用のEdit_boxを表示
 Const BIF_BROWSEINCLUDEFILES = &H4000 'ファイルも表示して選択できる
 Dim hWnd As Long
 Dim sPath As String
  
  hWnd = Application.hWnd

  Set oFolder = CreateObject("Shell.Application") _
    .BrowseForFolder _
      (hWnd, _
      "フォルダを選択して下さい", _
      BIF_RETURNNONLYFSDIRS Or BIF_EDITBOX, _
      CreateObject("WScript.Shell").Specialfolders("desktop"))
  If (oFolder Is Nothing) Then Exit Sub
  
  sPath = oFolder.Self.Path & "\"

 
 ' Dirで指定フォルダ内をLoop 画像をA列に貼り付け
 Dim fileName As String
 Dim c As Range
 Dim pos As Integer
 Dim szoom
  szoom = ActiveWindow.Zoom
  ActiveWindow.Zoom = 100
 
  '最初の画像貼り付けセル
  Set c = [A10]
  fileName = Dir$(sPath & "*.*")
  Do Until Len(fileName) = 0
    ' ファイル拡張子の判別
    pos = InStrRev(fileName, ".")
    If pos > 0 Then
      Select Case LCase$(Mid$(fileName, pos))
       Case ".jpeg", ".jpg", ".gif"
         c.Select
         '画像貼り付け(図の挿入)
         PasteImage sPath & fileName, c.Resize(15)
         
         Set c = c.Offset(20) '次の画像貼り付け位置
      End Select
    End If
    fileName = Dir()
  Loop
  
  ActiveWindow.Zoom = szoom
  MsgBox "画像の読込みが終了しました"
 
End Sub

'// 画像貼り付け(図の挿入) F列に 画像名
Private Sub PasteImage(fileName$, c As Range)
 Dim ratio As Double
  With ActiveSheet.Pictures.Insert(fileName).ShapeRange
    .Left = c.Left
    .Top = c.Top
    .LockAspectRatio = True
    ' 画像が大きい場合、画像サイズをセル高さに合わせる
    ratio = c.Height / .Height
    If ratio < 1# Then .Height = .Height * ratio
  End With
  c.Range("F1").Value = fileName 'または Dir$(filename)
  
End Sub

【71217】Re:写真を指定して貼り付ける
回答  ようちゃん  - 12/2/10(金) 22:20 -

引用なし
パスワード
   まずはお礼を言わせてください。本当にありがとうございます。

とてもすごいマクロありがとうございます。私素直に感動しました。マクロは将来役に立つと思い、講座をとっているのですが、プログラミングはどうも苦手のようで、うまく処理することが出来ませんでした。本当に本当にありがとうございます。将来こういうプログラムが書けるように、これから勉強を続けていきたいと思います。(まだ入門編ですが頑張ります(笑))このプログラムはこれから熟読して、一人では書けないながらも理解に努めていきたいと思います。

後一点どうしても教えて頂きたいのですが、このマクロの逆の処理は可能でしょうか?今は、「フォルダにある全ての画像をエクセルに貼り付ける→その画像名をF列に記入する」というプログラムを教えて頂きました。この操作の逆で「画像名をF列に記入する(前もって..例えば0745.JPGなどをF10,F20,F30…など一定間隔で記載)→フォルダにある画像からその画像名の画像を選択し、A列に同じ様に貼り付ける」このような処理は可能なものでしょうか?

現在行っている処理なのですが(まずはF列に数字を記載し、空白でなければA列に10を記入するプログラム)こういったプログラムが基本となると想像しています。これにファイルを読み込むプログラムと、画像を挿入するプログラムを組み合わせていくのかと思っております。

【F列に数字を記載し、空白でなければA列に10を記入するプログラム】
Sub Sample2()
Dim j As Long

For j = 1 To 100
If Cells(j, 6) <> "" Then
Cells(j, 1).Activate

ActiveCell.Value = 10
End If
Next j
End Sub

kanabunさんに教えて頂いた内容に比べてあまりに初歩的で恥ずかしいくらいなのですが、正直なところ現在はまだまだこのレベルです。お手数ですが、またお時間の許すときに教えて頂ければ嬉しいです。よろしくお願いいたします。

【71220】Re:写真を指定して貼り付ける
発言  kanabun  - 12/2/11(土) 9:43 -

引用なし
パスワード
   ▼ようちゃん さん:

>【F列に数字を記載し、空白でなければA列に10を記入するプログラム】
>Sub Sample2()
> Dim j As Long
>
> For j = 1 To 100
> If Cells(j, 6) <> "" Then
> Cells(j, 1).Activate
>
>ActiveCell.Value = 10
>End If
>Next j
>End Sub
これはなかなか参考になるコードです。このコードを見ただけで、書いた
人がどの程度VBAに習熟しているかが分かりますから。では、これを材料
にして、コードの記述法一般についておさらいしておきましょう。

'【F列に数字を記載し、空白でなければA列に10を記入するプログラム】
▼インデントをつける
まずコードにはインデントを付けてください。Loopの始まりの Forと
Loopの終了の Next が同じ桁位置にくるように、また、その中のコードは
TABで一段、段下げします。
If〜End If も同じです。(内部を段下げします)
Sub Sample2b()
 Dim j As Long
 
 For j = 1 To 100
   If Cells(j, 6) <> "" Then
     Cells(j, 1).Activate
     ActiveCell.Value = 10
   End If
 Next j
End Sub

▼不用意にセルをアクティブにしない
 あるセルに値を書き込む処理のために、セルをアクティブにする
 操作は不要です。
  セル.Value = 値
 これだけで十分です。
▼空白の判定は IsEmpty関数をつかう
>  If Cells(j, 6) <> "" Then
 これは、セルが 長さ0 の文字列と等しくなかったら、という記述
 をしています。ほんとは セルの「値が Empty でなかったら」を
 判定したいのではありませんか? そういう時は 組み込み関数の
 IsEmpty()を使います。 "" という文字列と比較するのはそのもの
 ズバリの判定法ではありません。
Sub Sample2c()
 Dim j As Long
 
 For j = 1 To 100
   If Not IsEmpty(Cells(j, 6).Value) Then
     Cells(j, 1).Value = 10
   End If
 Next j
End Sub

▼For 〜Next よりも For Each 〜Next のほうが高速
 セル範囲などのようなオブジェクトのコレクション内をLoopする
 ときは、For Each 〜Next でLoopしたほうが高速です。
Sub Sample2d()
 Dim f As Range
 
 For Each f In Range("F1:F100")
   If Not IsEmpty(f.Value) Then
     f.EntireRow.Range("A1").Value = 10
   End If
 Next f
End Sub

▼Loopしないで一括処理できないか、考えてみる
 これまでのコードは範囲内のセルをひとつづつ順に調査して判定
 し、処理するコードを書いていました。
 やりたいことが F列範囲内の「文字列が書き込まれているセル」の
 A列に数値を代入する、 ということなら、Loopしないで処理を記述
 する方法があります。
 プロシージャ・コードの最初の
>  On Error Resume Next
 は、SpecialCellsメソッドが 「範囲内に文字列が書き込まれている
 セル」がひとつもなかったときはエラーが発生し、コードの実行が
 中断してしまうので、エラーがあっても Resumeしてつぎに進むよ
 う進行を制御しています。
Sub Sample2e()
 On Error Resume Next
 With Range("F1:F100").SpecialCells(xlConstants, xlTextValues)
   .Offset(, -5).Value = 10
 End With
End Sub

※本題については、別スレの UO3 さんのサンプルも参考になさりながら、
もうしばらくご自分であがいてみてくださいな

【71229】Re:写真を指定して貼り付ける
お礼  ようちゃん  - 12/2/11(土) 21:50 -

引用なし
パスワード
   詳しい内容、ありがとうございます。
「ForNext」コード以外にも「For Each Next」の利用や、
エラーを無視するコード、インテンドを付けることなど、
基礎から応用まで詳しく教えてもらい感謝します。

VBAは少しでも深く理解したいので、
今日は新たにVBAの本を購入してきました。
別スレの UO3さんのコードもとても参考になるものと思います。
ひとまずは自分であがいてみて、何をお聞きしたらいいのか、
何がわかっていないのか、これからもう少しチャレンジを続けたいと思います。

考える機会も下さってありがとうございます。
また出来たらレスに書き込めたらと思いますので、
成長したコードを見てくださいね(笑)
丁寧なご回答を含めまして、いつも本当にありがとうございます。

1887 / 13645 ツリー ←次へ | 前へ→
ページ:  ┃  記事番号:
2610219
(SS)C-BOARD v3.8 is Free