[ 初めての方へ | 一覧(最新更新順) | 全文検索 | 過去ログ ]
『Excelマクロで行列削除実行後の「元に戻す」』(spacedragon)
いつもお世話になっております。
さて、今回はタイトルの件でご教示をお願いできればと思います。
マクロはもちろん元に戻すことは基本的にNGですが、個別に見た場合は
可能な場合もあると思います。
下記の行/列 削除マクロについて、削除前の状態に戻す方法が
ございましたらよろしくお願い致します。
尚、ブックやシートのバックアップは使用しない方法です。
Selection.delete Shift:=xlUp
もしくは
Selection.delete Shift:=xlToLeft
これらの処理の直前に削除対象行(列)をコピーして
クリップボードに格納して呼び出すことが可能であれば
できると思うのですが。。。
どうぞよろしくお願い致します。
< 使用 Excel:Excel2010、使用 OS:Windows10 >
>個別に見た場合は 可能な場合もあると思います。
>これらの処理の直前に削除対象行(列)をコピーして > クリップボードに格納して呼び出すことが可能であれば > できると思うのですが。。。
その処理を手作業でできますか?
(渡辺ひかる) 2019/12/23(月) 15:15
Sub 削除マクロ()
'予め"削除前"という名のシートを作成しておくこと
Set 対象シート = Selection.Parent Selection.Parent.Cells.Copy Sheets("削除前").Range("A1")
Selection.Delete Shift:=xlUp '削除処理
End Sub
Sub 戻すマクロ()
Sheets("削除前").Cells.Copy 対象シート.Range("A1") End Sub
(mm) 2019/12/23(月) 15:21
クリップボードにはWindowsのクリップボードとOfficeクリップボードがあります。
Windowsのクリップボードは、行を削除したときにがクリアされちゃうようです
Officeクリップボードは、データが蓄積されているようですが、 VBAから操作するのは、なかなか骨が折れるようです。
私はWindowsAPIはよくわからないので、 vba office clipboard とかをキーにして検索してください。
>尚、ブックやシートのバックアップは使用しない方法です。 なぜ、実現のハードルを自分であげちゃうのでしょう 実行結果が同じならばいいのでは?
mmさんご提案の方法が現実的だと思います。 (´・ω・`) 2019/12/23(月) 15:24
尚、ブックやシートのバックアップは使用しない方法です。
これはブックが巨大な場合に現実的ではないからです。
毎回数分待たされるのはまずいとの認識です。
でければこれを避けたいのですが。。。
(spacedragon) 2019/12/23(月) 15:52
Sub main()
Set 選択シート = Selection.Parent アドレス = Selection.Address Selection.Copy Sheets("削除前").Range(アドレス) 削除方向 = "xlUp" 'またはxlToLeft Selection.Delete Shift:=xlUp End Sub
Sub 戻す()
Sheets("削除前").Range(アドレス).Copy If 削除方向 = "xlUp" Then 選択シート.Range(アドレス).Insert Shift:=xlDown If 削除方向 = "xlToLeft" Then 選択シート.Range(アドレス).Insert Shift:=xlToRight 削除方向 = "" End Sub (mm) 2019/12/23(月) 16:45
バックアップしたブックがあるならば、例えば、現在のセル位置とその前後を元に、行を特定できそうな列を調べます。バックアップ元にもおそらく同じ内容の行が存在するでしょうから、そこからコピーして、今のシートに挿入する、というのはどうでしょうか?(バックアップファイルが複数ある場合は、自分のファイル名に似たもの全ての更新日時を調べ、一番新しいものを採用すれば良いでしょう)
(???) 2019/12/23(月) 17:21
単純に色々な「元に戻す」を実行前の選択セル(複数)をクリップボードに格納して呼び出すことができれば解決する可能性があると思ったものでご質問させて頂きました。
(spacedragon) 2019/12/23(月) 18:25
>個別に見た場合は可能な場合もある という前提なのに >このスクリプトでは対応できません。 とか、汎用性を求めているように見えますが?
〜〜〜〜〜〜〜〜〜〜
「元に戻す」可能性があるならば、マクロで削除するべきではないです。
>単純に色々な「元に戻す」を実行前の選択セル(複数)をクリップボードに格納して呼び出すことができ ても、削除でエラーになった数式は元には戻らないですが、それはどう考えますか? (チオチモリン) 2019/12/23(月) 23:30
一番問題なのは、ひとつのマクロについて
適用状況によって復元可能な場合と不可能な場合が出てくることで
さらに復元した結果が元と異なると、これはもう復元しないほうが
よかった!最悪〜
になることです。
簡単ではないですが、クリップボードを使用する方法はひとつのヒントになるのかな
と思ってここに質問させて頂きました。
可能性があるのならひとつひとつのマクロについて検討してみたいと
思った次第です。
世の中の
「Excelのオリジナル機能ではどんな複雑な処理でもちゃんと復元できるのに
マクロでは何故できないの?」
との単純な要望に応えられないのは大変遺憾ですが
やっぱり「マクロなので仕方ない」が結論なのでしょうか。
残念なことですが
それによって、大勢の「Excelアドインは致命的な欠陥があるので使いたくない」
といった人たちを遠ざけていることは確かなようで。。。
(spacedragon) 2019/12/24(火) 02:42
>「マクロなので仕方ない」 マクロの場合はその部分もコーディグする必要があるだけです。 出来ないわけではありません。 作る側の苦労の問題。 (cai) 2019/12/24(火) 09:41
ちょっと疑問です
>「Excelのオリジナル機能ではどんな複雑な処理でもちゃんと復元できるのに マクロでは何故できないの?」
シートの削除とかはUndo できませんよね?
>「Excelアドインは致命的な欠陥があるので使いたくない」
これは大きな誤解だと思います。 アドインのレベルにもよると思いますが、 アドインは特定の目的のために作成されたものであって、その目的以外に使用して「致命的な欠陥」と言われてはたまったものではありません。
「自動車は、事故ると大変なことになるので乗らない」と言っていることと同じだと思います。 使い方をロクに理解せずに使用して、自分のミスを棚上げして「欠陥」と言っているだけでしょう。
(渡辺ひかる) 2019/12/24(火) 10:10
渡辺ひかる様
確かにシートの削除とかはそうなんですが、ことシート内の編集に関しては
かなりの確率で元に戻せますよね。たとえオートフィルタとかがかかっていても。。。
ダメだと言っているのは実際にマクロを作らない人たちの意見なのですが、世の中一般はそうなんだろうと思います。それを否定すると「ユーザの意見を無視」になってしまうので真摯に拝聴はしたいと思っています。
(spacedragon) 2019/12/24(火) 12:33
>それを否定すると「ユーザの意見を無視」になってしまうので
対応の問題だと思いますけどね・・・
そのようなユーザーにはきちんと
Excel標準機能でUndoができる理由(履歴が記録されている) 通常のマクロではそれができない理由(通常ではそれは非常に難しい)
を説明してあげるのが、良いかと思います。
(渡辺ひかる) 2019/12/24(火) 13:14
例えばExcelアドインの老舗の「RelaxTools Addin」様では一部の機能について、「元に戻す」をサポートされていると聞きます。
https://software.opensquare.net/relaxtools/archives/1051/
ならば頑張ればある程度できるのでは?
と言われていまして今後検討していこうと思っている次第です。
(spacedragon) 2019/12/24(火) 14:43
コードは見ていないのでわかりませんが、例えば
文字の先頭に文字列挿入 の場合の「元に戻す」ならば、おそらく
挿入した文字列を文字の先頭から削除 という処理を行って
見かけ上
元に戻したようになるだけなのでは? (私ならそんなつくりにします)
(チオチモリン) 2019/12/24(火) 16:17
参考までですが Deleteメソッドを使わずに、下記のようなコードでセルを削除すれば Undoは効きますね
’標準モジュール Option Explicit
Private Declare Sub keybd_event Lib "user32.dll" ( _ ByVal bVk As Byte, _ ByVal bScan As Byte, _ ByVal dwFlags As Long, _ ByVal dwExtraInfo As Long)
Private Const VK_APP = &H5D Private Const KEYEVENTF_KEYUP = &H2 Sub test() If TypeName(Selection) <> "Range" Then Exit Sub If Selection.Cells.Count = 1 Then keybd_event VK_APP, 0, 0, 0 keybd_event VK_APP, 0, KEYEVENTF_KEYUP, 0 SendKeys "d" SendKeys "u" SendKeys "{ENTER}" End If End Sub
(渡辺ひかる) 2019/12/24(火) 17:46
いや別に1セルだからできるのではないです。
たまたま、サンプルとして提示したものが1セルだっただけです。
選択範囲を判断して、分岐処理すれば、応用は効くと思います。
ただし、あらゆるイレギュラーを想定しなければならないとは思います。
(渡辺ひかる) 2019/12/24(火) 18:27
渡辺ひかるさんのコードが機能するのは、マクロからキーを送ってExcelを操作しているから、実際に削除するのはマクロではなくExcel本体なので、Undoが効くのです。 ただ、SendKeysはその瞬間にアクティブなウィンドウに文字列を送ってしまうので、アプリ切替とかすると誤動作する原因になりやすいので、推奨されない方法なのです。
RelaxTools AddinではUndoできる、というのは、マクロ内で1行覚えているのだろうと思います。 Excel仕様だからUndoできないのが当然であり、マクロで実現するなら工数と金をよこせ、と言って良いと思いますよ。(以前はExcelヘルプの中に、マクロで操作した分はUndoできない事が書かれていましたが、今探してみると無くなっているみたいです。古いヘルプを削除するのはやめて欲しいものです…)
(???) 2019/12/25(水) 09:56
>推奨されない方法なのです。
おっしゃる通りです。自分でやろうとは思いませんし、勧めもしませんが 質問者さんがこだわっているので、あえて掲示しました。
>今探してみると無くなっているみたいです。
こちらExcel2010ですが、まだ書いてありました。 以下ヘルプ抜粋
Undo メソッドは、マクロを実行する前にユーザーが実行した最後の操作を元に戻す場合にだけ使用できます。このメソッドは、マクロの先頭に記述する必要があります。Visual Basic で実行したコマンドは元に戻すことができません。
(渡辺ひかる) 2019/12/25(水) 10:06
本件は一旦保留にしてユーザ様のご理解を得たいと思います。
僕のExcelアドイン「SuperXLe」が仮にメジャーになってExcel本体への組み込みニーズが高まってMS社様に採用頂くことになれば実現をお願いしてみます。(笑)
可能性が全くゼロではないので少しでもメジャーになれるようにこれからも努力します。
どうぞよろしくお願い致します。
(spacedragon) 2019/12/25(水) 14:01
その後、Application.OnUndo にコピーした範囲を元に戻すをロジックを登録しています。
上記の処理を自作のフレームワーク内に組み込んで置き、範囲指定でセルを変更するものについてはUNDOが効くようにしています。
ソース内のSelectionFrameWork あたりをあさってみてください。
(RelaxToolsの中の人) 2019/12/26(木) 21:18
ご丁寧にありがとうございます。
明日から連休にはいりますので、いろいろやってみます。
貴殿のツールをいつも参考にさせて頂いております。
取り急ぎお礼まで。。。
(spacedragon) 2019/12/27(金) 10:12
[ 一覧(最新更新順) ]
YukiWiki 1.6.7 Copyright (C) 2000,2001 by Hiroshi Yuki.
Modified by kazu.