Excel VBA質問箱 IV

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

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


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

【76601】画像の移動 vbaビギナー 15/2/6(金) 14:23 質問[未読]
【76602】Re:画像の移動 β 15/2/6(金) 19:49 発言[未読]
【76603】Re:画像の移動 β 15/2/6(金) 20:45 発言[未読]
【76606】Re:画像の移動 vbaビギナー 15/2/9(月) 8:33 お礼[未読]
【76604】Re:画像の移動 マナ 15/2/7(土) 13:54 発言[未読]
【76605】Re:画像の移動 マナ 15/2/7(土) 17:34 発言[未読]
【76607】Re:画像の移動 vbaビギナー 15/2/9(月) 8:37 お礼[未読]

【76601】画像の移動
質問  vbaビギナー  - 15/2/6(金) 14:23 -

引用なし
パスワード
   初めて質問させて頂きます。

VBAを使用して社内業務の一部簡略化を図るべく
手探りで組んでみているのですがどうしても分からないので
どなたかお力添えお願いします。

こちらでやりたい事は特定の文字を入力すると、それに対応した画像を特定のシート上の
特定の座標(セルでも可)へ移動したいというものです。

いろいろなサイトを参考にし、自分なりに作ってみたものの、綺麗に収まらず困っています。
こちらが作成したコードです。


Private Sub Worksheet_Change(ByVal Target As Range)
If Intersect(Target, Range("A1:A10")) Is Nothing Then Exit Sub
If Target.Count <> 1 Then Exit Sub
Select Case Target.Value
Case "みかん"
Shapes(1).Top = Target.Top
Shapes(1).Left = Target.Width
Case "りんご"
Shapes(2).Top = Target.Top
Shapes(2).Left = Target.Width
Case "さかな"
Shapes(3).Top = Target.Top
Shapes(3).Left = Target.Width
Case "牛乳"
Shapes(4).Top = Target.Top
Shapes(4).Left = Target.Width
Case "こおり"
Shapes(5).Top = Target.Top
Shapes(5).Left = Target.Width
End Select
End Sub

この状態だと、画像が元の場所に戻らないため、画像が重なってしまうことがあります。
そこで画像は、入力されていない場合は元の場所に戻るように改良を加えたいのです。

このコードを使用しなくても構いません。
どなたかヒントを頂けませんか?

【76602】Re:画像の移動
発言  β  - 15/2/6(金) 19:49 -

引用なし
パスワード
   ▼vbaビギナー さん:

こんばんは

まず、元の位置に戻すには、元の位置がどこだったかを認識しなければいけません。
以下は、ブックを開いたときに、元の位置を把握しておき、Changeイベントで参照します。
なお、A列の横に移動している図をそのままにしてブックを保存すると、次回、ブックを開いたときに
元の位置がわからなくなるので、保存前に強制的に元の位置に戻します。

ThisWorkBookモジュールを使いますので、いっそのこと、ChangeイベントもThisWorkbookモジュールに
移します。(シートモジュールのままでもいいのですが、以下の例は、Changeイベントも移すコードです)

まず、シートモジュールのコードを消去してください。

(ThisWorkbookモジュール)

Private Sub Workbook_Open()
  StoreOriginal
End Sub

Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean)
  ResetOriginal
End Sub

Private Sub Workbook_SheetChange(ByVal Sh As Object, ByVal Target As Range)
  If Sh.Name <> SHN Then Exit Sub
  If Intersect(Target, Sh.Range("A1:A10")) Is Nothing Then Exit Sub
  If Target.Count <> 1 Then Exit Sub
  
  ResetOriginal
  
  Select Case Target.Value
    Case "みかん"
      Sh.Shapes(1).top = Target.top
      Sh.Shapes(1).left = Target.Width
    Case "りんご"
      Sh.Shapes(2).top = Target.top
      Sh.Shapes(2).left = Target.Width
    Case "さかな"
      Sh.Shapes(3).top = Target.top
      Sh.Shapes(3).left = Target.Width
    Case "牛乳"
      Sh.Shapes(4).top = Target.top
      Sh.Shapes(4).left = Target.Width
    Case "こおり"
      Sh.Shapes(5).top = Target.top
      Sh.Shapes(5).left = Target.Width
  End Select

End Sub

(標準モジュール)

Option Explicit

Type pos
  left As Double
  top As Double
End Type

Public s1 As pos
Public s2 As pos
Public s3 As pos
Public s4 As pos
Public s5 As pos

Public Const SHN As String = "Sheet1"   '該当シート名

Sub StoreOriginal()
  With Sheets(SHN)
    s1.left = .Shapes(1).left
    s1.top = .Shapes(1).top
    s2.left = .Shapes(2).left
    s2.top = .Shapes(2).top
    s3.left = .Shapes(3).left
    s3.top = .Shapes(3).top
    s4.left = .Shapes(4).left
    s4.top = .Shapes(4).top
    s5.left = .Shapes(5).left
    s5.top = .Shapes(5).top
  End With
End Sub

Sub ResetOriginal()
  With Sheets(SHN)
    .Shapes(1).left = s1.left
    .Shapes(1).top = s1.top
    .Shapes(2).left = s2.left
    .Shapes(2).top = s2.top
    .Shapes(3).left = s3.left
    .Shapes(3).top = s3.top
    .Shapes(4).left = s4.left
    .Shapes(4).top = s4.top
    .Shapes(5).left = s5.left
    .Shapes(5).top = s5.top
  End With
End Sub

【76603】Re:画像の移動
発言  β  - 15/2/6(金) 20:45 -

引用なし
パスワード
   ▼vbaビギナー さん:

こんばんは

運用保守を考えると、↑でアップした方法より以下がいいかと思い直しました。
隠しシート(非表示でもOK)を用意し、そこに【元の図の位置】を格納しておきます。

1.各図をしかるべき【元の位置】に配置した状態で、StoreOriginal を実行してください。
  これは、元の図の位置を変更したら、その時にも実行してください。
2.シート上の操作は従来と同じです。

コードは、逆にシートモジュール一本にしました。
標準モジュールやThisWOrkbookモジュールのコードは消去してください。
なお、隠しシート名を仮に "SHeet2" にしてあります。

いずれかの図がA列のそばに移動している状態で保存しますと、次回、開いた際にも
移動したままで表示されますが、他の図を選ぶと、元の位置にもどります。

(シートモジュール)

Option Explicit

Const SHN As String = "Sheet2"   '隠しシート名

Private Sub Worksheet_Change(ByVal Target As Range)

  If Intersect(Target, Range("A1:A10")) Is Nothing Then Exit Sub
  If Target.Count <> 1 Then Exit Sub
  
  ResetOriginal
  
  Select Case Target.Value
    Case "みかん"
      Shapes(1).top = Target.top
      Shapes(1).left = Target.Width
    Case "りんご"
      Shapes(2).top = Target.top
      Shapes(2).left = Target.Width
    Case "さかな"
      Shapes(3).top = Target.top
      Shapes(3).left = Target.Width
    Case "牛乳"
      Shapes(4).top = Target.top
      Shapes(4).left = Target.Width
        Case "こおり"
      Shapes(5).top = Target.top
      Shapes(5).left = Target.Width
  End Select
End Sub

Sub StoreOriginal()
  With Sheets(SHN)
    .Range("A1").Value = Shapes(1).left
    .Range("A2").Value = Shapes(1).top
    .Range("A3").Value = Shapes(2).left
    .Range("A4").Value = Shapes(2).top
    .Range("A5").Value = Shapes(3).left
    .Range("A6").Value = Shapes(3).top
    .Range("A7").Value = Shapes(4).left
    .Range("A8").Value = Shapes(4).top
    .Range("A9").Value = Shapes(5).left
    .Range("A10").Value = Shapes(5).top
  End With
End Sub

Sub ResetOriginal()
  With Sheets(SHN)
    Shapes(1).left = .Range("A1").Value
    Shapes(1).top = .Range("A2").Value
    Shapes(2).left = .Range("A3").Value
    Shapes(2).top = .Range("A4").Value
    Shapes(3).left = .Range("A5").Value
    Shapes(3).top = .Range("A6").Value
    Shapes(4).left = .Range("A7").Value
    Shapes(4).top = .Range("A8").Value
    Shapes(5).left = .Range("A9").Value
    Shapes(5).top = .Range("A10").Value
  End With
End Sub

【76604】Re:画像の移動
発言  マナ  - 15/2/7(土) 13:54 -

引用なし
パスワード
   私も考えてみました。
元位置は、セルのコメントに記録するようにしています。
予め、画像には名前をつけておいてください。

Private Sub Worksheet_Change(ByVal Target As Range)
  Dim r As Range
  Dim p As Picture
  Dim s As String
  Dim c As Range
  Dim v
 
  Set r = Range("A1:A10")

  If Intersect(Target, r) Is Nothing Then Exit Sub
  If Target.Count <> 1 Then Exit Sub
  
  On Error Resume Next
  Set p = Pictures(Target.Value)
  On Error GoTo 0
  
  If p Is Nothing Then
    MsgBox "その名前の画像はありません"
    Application.EnableEvents = False
    Application.Undo
    Application.EnableEvents = True
    Exit Sub
  End If
  
  Application.EnableEvents = False
  For Each c In r
    s = c.NoteText
    If s <> "" Then
      v = Split(s, ",")
      With Shapes(v(0))
        .Top = v(1)
        .Left = v(2)
      End With
    End If
    If c.Address <> Target.Address Then
      c.ClearComments
      c.ClearContents
    End If
  Next
  Application.EnableEvents = True
  
  Target.NoteText p.Name & "," & p.Top & "," & p.Left
  p.Top = Target.Top
  p.Left = Target.Width

End Sub

【76605】Re:画像の移動
発言  マナ  - 15/2/7(土) 17:34 -

引用なし
パスワード
   画像名の入力をリストから選択するようにしました
入力値削除で、元の位置に戻せるようにしました

Option Explicit

Const myAdr As String = "A1:A10"


Private Sub Worksheet_Change(ByVal Target As Range)
  Dim r As Range
  Dim p As Picture
  Dim s As String
  Dim c As Range
  Dim v
 
  Set r = Range(myAdr)

  If Intersect(Target, r) Is Nothing Then Exit Sub
  If Target.Count <> 1 Then Exit Sub
'
  On Error Resume Next
  Set p = Pictures(Target.Value)
  On Error GoTo 0
 
  If Target.Value <> "" Then
    If p Is Nothing Then
      MsgBox "その名前の画像はありません"
      Application.EnableEvents = False
      Application.Undo
      Application.EnableEvents = True
      Exit Sub
    End If
  End If
  
  Application.EnableEvents = False
  For Each c In r
    s = c.NoteText
    If s <> "" Then
      v = Split(s, ",")
      With Pictures(v(0))
        .Top = v(1)
        .Left = v(2)
      End With
    End If
    If c.Address <> Target.Address Then
      c.ClearComments
      c.ClearContents
    End If
  Next
  Application.EnableEvents = True
  
  If Target.Value = "" Then
    Target.ClearComments
    Exit Sub
  End If
  
  Target.NoteText p.Name & "," & p.Top & "," & p.Left
  p.Top = Target.Top
  p.Left = Target.Width

End Sub


Private Sub Worksheet_SelectionChange(ByVal Target As Range)
  Dim r As Range
  Dim p As Picture
  Dim myList

  Set r = Range(myAdr)

  If Intersect(Target, r) Is Nothing Then Exit Sub
  If Target.Count <> 1 Then Exit Sub

  For Each p In Pictures
    myList = myList & "," & p.Name
  Next

  With r.Validation
    .Delete
    .Add Type:=xlValidateList, Formula1:=myList
    .ShowError = False
    .IgnoreBlank = True
  End With
  
End Sub

【76606】Re:画像の移動
お礼  vbaビギナー  - 15/2/9(月) 8:33 -

引用なし
パスワード
   ▼β さん:
回答ありがとうございます。
返信が遅れてしまい、申し訳ありません。
さっそく試してみたいと思います。

【76607】Re:画像の移動
お礼  vbaビギナー  - 15/2/9(月) 8:37 -

引用なし
パスワード
   ▼マナ さん:
回答ありがとうございます。
返信が遅れてしまい申し訳ありませんでした。
これを参考にして、試行錯誤していこうと思います。

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