Excel VBA質問箱 IV

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

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


5361 / 13644 ツリー ←次へ | 前へ→

【51249】Application.Sendkeysで送ったコマンドが実行されるのを待つ方法 やまP 07/9/5(水) 21:15 質問[未読]
【51253】Re:Application.Sendkeysで送ったコマンド... neptune 07/9/5(水) 22:23 発言[未読]
【51289】Re:Application.Sendkeysで送ったコマンド... やまP 07/9/10(月) 15:10 お礼[未読]
【51254】Re:Application.Sendkeysで送ったコマンド... ichinose 07/9/5(水) 23:21 発言[未読]
【51256】Re:Application.Sendkeysで送ったコマンド... neptune 07/9/6(木) 9:56 発言[未読]
【51291】Re:Application.Sendkeysで送ったコマンド... やまP 07/9/10(月) 15:44 お礼[未読]
【51257】マクロじゃないけど。 Jaka 07/9/6(木) 11:23 発言[未読]
【51258】Re:マクロじゃないけど。 Jaka 07/9/6(木) 11:51 発言[未読]
【51293】Re:マクロじゃないけど。 やまP 07/9/10(月) 15:55 お礼[未読]
【51294】解決致しました! やまP 07/9/10(月) 16:09 お礼[未読]

【51249】Application.Sendkeysで送ったコマンドが...
質問  やまP E-MAIL  - 07/9/5(水) 21:15 -

引用なし
パスワード
   やりたいと思っている処理は以下の通りです。
1.現在セル(C2:E4)を選択しているとする。(選択の中心はC2)
2.ショートカットキー(Alt+4)を押すと、2〜4行全体が削除される。
3.その後、選択セルがC2に戻る。
4.Undo(Ctrl+Zなど)を行えばきちんと前の状態に戻るようにする。

この処理のために以下の準備を行いました。
**********************************************************************
VBAコード:

Sub 選択している行全体を削除()
' Keyboard Shortcut: Alt+E+4

  Dim nowColumn As Variant '今選択の中心にあるセルの列
  Dim seru As Range '選択しているセルの範囲
  Dim min_flag As Boolean '選択セルの最小行を判定するフラグ
  Dim rowMin As Variant '選択セルの最小行
  Dim rowMax As Variant '選択セルの最大行
  Dim columnMin As Variant '選択セルの最小列
  Dim columnMax As Variant '選択セルの最大列
  
  nowColumn = Selection.Column '選択の中心にあるセルの列を代入
  min_flag = True
  
  '選択している範囲の中で最小行・列、最大行・列を求める
  For Each seru In Selection
    If (min_flag = True) Then
      rowMin = seru.Row
      columnMin = seru.Column
      min_flag = False
    End If
    rowMax = seru.Row
    columnMax = seru.Column
  Next

  '選択範囲の行全体を選択する
  Rows(rowMin & ":" & rowMax).Select
  
  'Alt+E+Dのコマンドを送る(これで行の削除を実行)
  Application.SendKeys ("%ED")
 
  '最初に選択していたセルを選択する
  Range(Cells(rowMin, columnMin), Cells(rowMax, columnMax)).Select
End Sub

メニューのユーザ設定:
・メニューの「編集」に、「選択している行全体を削除(4)」のメニューをカスタマイズ(マクロ)で追加。
・そこに、上記のマクロを設定

**********************************************************************
以上のことにより、やりたいと思っていることが実行されると思ったのですが、なぜか「行全体の削除」ではなく、「選択されているセルの削除」が実行されてしまいます。
ちなみに、最後の、
  >'最初に選択していたセルを選択する
  >Range(Cells(rowMin, columnMin), Cells(rowMax, columnMax)).Select
を除けばうまく実行されます。

恐らく、Application.Sendkeysで、コマンドが実行されるより先に最後の
  >'最初に選択していたセルを選択する
  >Range(Cells(rowMin, columnMin), Cells(rowMax, columnMax)).Select
が実行されてしまっているのかと思われます。

Sleepでコマンドの実行を待つ、なども考えましたがうまくいきません。

※直接マクロで処理を行わず、Application.Sendkeysでコマンドを送っているのは、Undoを可能にするためです。

**********************************************************************
非常に分かりにくい質問で恐縮ですが、どなたか良い対処法を思いつく方は教えてください。お願いします。

【51253】Re:Application.Sendkeysで送ったコマン...
発言  neptune  - 07/9/5(水) 22:23 -

引用なし
パスワード
   こんにちは

やったことないし、思いつきだけで実験もしてないので
そのつもりでお願いします。
本来は余りやりたくない手段ですが、最後の手段?ということで。

セルを削除するとWorksheet_Changeイベントが発生する見たいなのでこれを利用する。
1.Flgを広域変数として持つ
public flg as boolean
Changeイベントで
flg=true
にする。

2.Sub 選択している行全体を削除 内で待つ処理を追加
'Alt+E+Dのコマンドを送る(これで行の削除を実行)
flg=false '初期設定
  Application.SendKeys ("%ED")
'フラグがTrueになるのを待つ
do until flg=true
doevents
loop

じゃ駄目ですかね??

【51254】Re:Application.Sendkeysで送ったコマン...
発言  ichinose  - 07/9/5(水) 23:21 -

引用なし
パスワード
   こんばんは。
>やりたいと思っている処理は以下の通りです。
>1.現在セル(C2:E4)を選択しているとする。(選択の中心はC2)
>2.ショートカットキー(Alt+4)を押すと、2〜4行全体が削除される。
>3.その後、選択セルがC2に戻る。
>4.Undo(Ctrl+Zなど)を行えばきちんと前の状態に戻るようにする。
>
>※直接マクロで処理を行わず、Application.Sendkeysでコマンドを送っているのは、Undoを可能にするためです。

ふ〜ん、これ本当ですか??

Excel2002で例えば、

Sub test1()
  With Rows(1)
    .Select
    .Value = 1
    End With
  Application.SendKeys "%ed"
  DoEvents
  'MsgBox "確認"
  Application.SendKeys "^z"
  DoEvents
  Range("a1:c1").Select
End Sub

とすれば、1行目がSendkeysによって削除されますが、Undoは効きませんでした。
(エラーにはなりませんが)
これがバージョンによっては成功するのですか?

Excel2002でUndoを成功させるには・・・、

'===============================================
Sub test()
  With Rows(1)
    .Select
    .Value = 1
    End With
  With Range("a1:c1")
    .Value = 2
    .Select
    End With
  MsgBox "確認1"
  Application.ExecuteExcel4Macro "EDIT.DELETE(3)"
  MsgBox "確認2"
  Application.Undo
  Range("a1:c1").Select
End Sub


上記コードのようにExcel4Macroでの行削除はUndoが有効でした。

バージョンが違うのなら、確認してみて下さい

【51256】Re:Application.Sendkeysで送ったコマン...
発言  neptune  - 07/9/6(木) 9:56 -

引用なし
パスワード
   ▼ichinose さん:
こんにちは

>とすれば、1行目がSendkeysによって削除されますが、Undoは効きませんでした。
>(エラーにはなりませんが)
>これがバージョンによっては成功するのですか?
>
>上記コードのようにExcel4Macroでの行削除はUndoが有効でした。
へえ〜そうなんですか!!

やはりよく言われるように、自分で操作、データを保存しておくなどの機能を
実装する手法が硬いんですね。

こういうのを見つけました。
「Creating An Undo Handler To Undo Changes Done By Excel VBA」
h t t p://www.jkp-ads.com/Articles/UndoWithVBA00.asp
英語なんで、細かくは見てないですが、これも「記録方式」みたいです。

【51257】マクロじゃないけど。
発言  Jaka  - 07/9/6(木) 11:23 -

引用なし
パスワード
   >1.現在セル(C2:E4)を選択しているとする。(選択の中心はC2)
>2.ショートカットキー(Alt+4)を押すと、2〜4行全体が削除される。
>3.その後、選択セルがC2に戻る。
>4.Undo(Ctrl+Zなど)を行えばきちんと前の状態に戻るようにする。

現在セル(C2:E4)を選択している時に
1、Shift + Space
2、Altを押しながら
  E → D
3、矢印キー(好きなもの)

これじゃダメ?
>3.その後、選択セルがC2に戻る。
これが1発でできないけど。

【51258】Re:マクロじゃないけど。
発言  Jaka  - 07/9/6(木) 11:51 -

引用なし
パスワード
   追加
>1、Shift + Space
これを
Ctrl + Space
にすれば、列にも対応できます。

【51289】Re:Application.Sendkeysで送ったコマン...
お礼  やまP  - 07/9/10(月) 15:10 -

引用なし
パスワード
   ▼neptune さん:
>こんにちは
>
>やったことないし、思いつきだけで実験もしてないので
>そのつもりでお願いします。
>本来は余りやりたくない手段ですが、最後の手段?ということで。
>
>セルを削除するとWorksheet_Changeイベントが発生する見たいなのでこれを利用する。
>1.Flgを広域変数として持つ
>public flg as boolean
>Changeイベントで
>flg=true
>にする。
>
>2.Sub 選択している行全体を削除 内で待つ処理を追加
>'Alt+E+Dのコマンドを送る(これで行の削除を実行)
>flg=false '初期設定
>  Application.SendKeys ("%ED")
>'フラグがTrueになるのを待つ
>do until flg=true
>doevents
>loop
>
>じゃ駄目ですかね??

>neptuneさん
遅くなって申し訳ありません。
ご回答ありがとうございます。

おっしゃった通りやってみたところ、
イベントを待ってからセル選択する部分はうまくいきました!
なるほど、Worksheet_Changeイベントを活用する手があるんですね。

ただ、これだと、Undoが効かなくなるみたいなんです。
ちょっと理由は分かりませんが…。

あと質問には書いていませんでしたが、Worksheet_ChangeイベントってそのSheetのみに有効ですよね?
PERSONAL.XLSのVBAに記述しても全てのSheetに適用はされませんよね?
できれば、エクセルを開いたときに常にこの機能を使えるようにしたいのですが・・・。

ちょっと自分でももう少し考えてみます。
どうもありがとうございます!

【51291】Re:Application.Sendkeysで送ったコマン...
お礼  やまP  - 07/9/10(月) 15:44 -

引用なし
パスワード
   ▼ichinose さん:
>こんばんは。
>>やりたいと思っている処理は以下の通りです。
>>1.現在セル(C2:E4)を選択しているとする。(選択の中心はC2)
>>2.ショートカットキー(Alt+4)を押すと、2〜4行全体が削除される。
>>3.その後、選択セルがC2に戻る。
>>4.Undo(Ctrl+Zなど)を行えばきちんと前の状態に戻るようにする。
>>
>>※直接マクロで処理を行わず、Application.Sendkeysでコマンドを送っているのは、Undoを可能にするためです。
>
>ふ〜ん、これ本当ですか??
>
>Excel2002で例えば、
>
>Sub test1()
>  With Rows(1)
>    .Select
>    .Value = 1
>    End With
>  Application.SendKeys "%ed"
>  DoEvents
>  'MsgBox "確認"
>  Application.SendKeys "^z"
>  DoEvents
>  Range("a1:c1").Select
>End Sub
>
>とすれば、1行目がSendkeysによって削除されますが、Undoは効きませんでした。
>(エラーにはなりませんが)
>これがバージョンによっては成功するのですか?
>
>Excel2002でUndoを成功させるには・・・、
>
>'===============================================
>Sub test()
>  With Rows(1)
>    .Select
>    .Value = 1
>    End With
>  With Range("a1:c1")
>    .Value = 2
>    .Select
>    End With
>  MsgBox "確認1"
>  Application.ExecuteExcel4Macro "EDIT.DELETE(3)"
>  MsgBox "確認2"
>  Application.Undo
>  Range("a1:c1").Select
>End Sub
>
>
>上記コードのようにExcel4Macroでの行削除はUndoが有効でした。
>
>バージョンが違うのなら、確認してみて下さい


>ichinoseさん
ありがとうございます。
確かに1つ目の方法だとUndoが有効にならず、2つ目ではうまくいきました。
僕のエクセルも2002なので、動作が同じでした。

恐らく、セルに影響を与えるようなマクロの処理を挟んだ時点でそれまでの処理記録のようなものがなくなってしまうのではないかと思いました。

test1は、
Sub test1()
  Rows(1).Select
  Application.SendKeys "1^{Enter}"
  Application.SendKeys "%ed"
'  DoEvents
'  MsgBox "確認"
'  Application.SendKeys "^z"
'  DoEvents
'  Range("a1:c1").Select
End Sub
とするとUndoが有効になりました。
SendKeysでコマンドを送っているだけならUndoが有効なのでしょうか。

あとichinoseさんのtest()を参考にすると、もしかしたら、Application.*に関してはUndoが有効になるのかとも思いました。
ちょっと確認してみたいと思います。

どうもありがとうございました。

【51293】Re:マクロじゃないけど。
お礼  やまP  - 07/9/10(月) 15:55 -

引用なし
パスワード
   ▼Jaka さん:
>追加
>>1、Shift + Space
>これを
>Ctrl + Space
>にすれば、列にも対応できます。

>Jakaさん
どうもありがとうございます。
Shift+Spaceなんて方法があったのですね!
基礎を知らなくて申し訳ありません。
それなら行選択の時に、あんな複雑にしなくても、
Application.SendKeys ("+ ")
でOKだったのですね!

元のセルを選択する方法は皆さんの意見を参考にもう少し考えてみたいと思います。

【51294】解決致しました!
お礼  やまP  - 07/9/10(月) 16:09 -

引用なし
パスワード
   ▼やまP さん:
>やりたいと思っている処理は以下の通りです。
>1.現在セル(C2:E4)を選択しているとする。(選択の中心はC2)
>2.ショートカットキー(Alt+4)を押すと、2〜4行全体が削除される。
>3.その後、選択セルがC2に戻る。
>4.Undo(Ctrl+Zなど)を行えばきちんと前の状態に戻るようにする。
>
>この処理のために以下の準備を行いました。
>**********************************************************************
>VBAコード:
>
>Sub 選択している行全体を削除()
>' Keyboard Shortcut: Alt+E+4
>
>  Dim nowColumn As Variant '今選択の中心にあるセルの列
>  Dim seru As Range '選択しているセルの範囲
>  Dim min_flag As Boolean '選択セルの最小行を判定するフラグ
>  Dim rowMin As Variant '選択セルの最小行
>  Dim rowMax As Variant '選択セルの最大行
>  Dim columnMin As Variant '選択セルの最小列
>  Dim columnMax As Variant '選択セルの最大列
>  
>  nowColumn = Selection.Column '選択の中心にあるセルの列を代入
>  min_flag = True
>  
>  '選択している範囲の中で最小行・列、最大行・列を求める
>  For Each seru In Selection
>    If (min_flag = True) Then
>      rowMin = seru.Row
>      columnMin = seru.Column
>      min_flag = False
>    End If
>    rowMax = seru.Row
>    columnMax = seru.Column
>  Next
>
>  '選択範囲の行全体を選択する
>  Rows(rowMin & ":" & rowMax).Select
>  
>  'Alt+E+Dのコマンドを送る(これで行の削除を実行)
>  Application.SendKeys ("%ED")
> 
>  '最初に選択していたセルを選択する
>  Range(Cells(rowMin, columnMin), Cells(rowMax, columnMax)).Select
>End Sub
>
>メニューのユーザ設定:
>・メニューの「編集」に、「選択している行全体を削除(4)」のメニューをカスタマイズ(マクロ)で追加。
>・そこに、上記のマクロを設定
>
>**********************************************************************
>以上のことにより、やりたいと思っていることが実行されると思ったのですが、なぜか「行全体の削除」ではなく、「選択されているセルの削除」が実行されてしまいます。
>ちなみに、最後の、
>  >'最初に選択していたセルを選択する
>  >Range(Cells(rowMin, columnMin), Cells(rowMax, columnMax)).Select
>を除けばうまく実行されます。
>
>恐らく、Application.Sendkeysで、コマンドが実行されるより先に最後の
>  >'最初に選択していたセルを選択する
>  >Range(Cells(rowMin, columnMin), Cells(rowMax, columnMax)).Select
>が実行されてしまっているのかと思われます。
>
>Sleepでコマンドの実行を待つ、なども考えましたがうまくいきません。
>
>※直接マクロで処理を行わず、Application.Sendkeysでコマンドを送っているのは、Undoを可能にするためです。
>
>**********************************************************************
>非常に分かりにくい質問で恐縮ですが、どなたか良い対処法を思いつく方は教えてください。お願いします。

>皆様
皆様のご意見を参考にして、試してみたところ、以下のモジュールで全てうまくいきました!

Sub 選択している行全体を削除()
 Application.SendKeys ("+ ")

 Application.SendKeys ("%ED")

 Application.SendKeys ("{Up}{Down}")
End Sub

こんなに単純にできるとは…。
複雑な質問でご迷惑をおかけしましたが、皆様のご回答がヒントになりました。
どうもありがとうございました!

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