質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

89.96%

VBA セルの初期状態を保持して置いて、処理後にその情報をもとにセルデータを元に戻したいです。

解決済

回答 4

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 4,395

King_of_Flies

score 312

現在VBAにて下記のような処理を考えています。

前提 Excelの数式タブ>名前の管理にて、
Range("A1:D3")を"InitDataRange"と命名していることとします。

今回の処理としてテンプレートシートを起点に下記のような処理がループで行われます。

1、テンプレートシートの初期状態を回避
2、テンプレートシートのデータを編集(ここの処理ではいろいろやっていますが、割愛)
3、テンプレートシートを別Bookに出力
4、テンプレートシートを初期状態に戻す

ここで今悩んでいるところが、1の処理と4の処理のところです。

以下、プログラムを見ていただきたく思います。

Sub test()
    '初期状態のRangeを回避します。
    Dim initRange As Range
    Set initRange = Range("InitDataRange")
    '2の処理の代わりに内部データをいじっています。出力処理は割愛。
    Range("A1").Value = "a"
    Range("A2").Value = "b"
    Range("D3").Value = "c"
  '初期状態に戻します。
  Range("InitDataRange") = initRange
End Sub

ここでできていないのが、最終行のRange~の部分です。
もともとデータが入っているのにもかかわらず、この処理を走らせると最終的に
Range("InitDataRange")の範囲は空になってしまします。

Excelの背景色の設定も含めて初期状態を回避し、
最後に戻すという処理を組み込みたいのですが、
簡単なやり方はありますでしょうか。

よろしくお願いいたします。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 4

checkベストアンサー

+1

テンプレートって?

「テンプレートに直接書き込む」ということ自体に抵抗を感じるので、私もttyp03さんの考え方の方がしっくりきます。

「変更したあと初期状態に戻したい。そのために初期状態を退避しておきたい。」
テンプレートとは、もともとそのために用意するものではないでしょうか。

せっかくテンプレートを用意しているのに、直接書き込んでテンプレートとしては使えなくなってしまうから、書き換える前に退避しておくって、ちょっと無駄を感じます。

テンプレートは参照するだけ

「テンプレートを変更しない」方針で考えると、以下のような処理になると思います。

1、出力用シートを作成する
2、テンプレートシートの内容を出力用シートにコピーする(出力シートの初期化処理)
3、出力用シートのデータを編集(ここの処理ではいろいろやっていますが、割愛)
4、出力用シートを別Bookに出力
5、出力用シートを初期化する(つまり2に戻る)

テンプレートシートの内容は終始参照されるだけで、変更はしません。

出力シートは毎回作成した方がきれいな状態ではじめられそうですが、速度を懸念されるようなら最初に作ったものを使いまわして、毎回テンプレートからのコピペでリセットだけすればよいと思います。

シートをキレイにするという意味で、対象範囲だけでなく以下のようにシート全体のコピペでまるごとリセットしてしまうのも手です。

Dim shTmpl As WorkSheet
Dim shOutput As WorkSheet
Set shTmpl = Sheets("Template")   'テンプレートシート ※シート名は適当
Set shOutput = Sheets("Output")   '出力用シート ※シート名は適当

'シート全体のコピペ
shTmpl.Copy shOutput

参考になれば幸いです。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/01/29 22:13

    おっしゃる通りだと思います。テンプレートをコピーして、複製に対して目的の処理をするべきです。
    もう少し大きなプログラムになると、やってるうちに、「あれ?どっちがテンプレート」なんて初歩的なミスが生じてくるはずです。(私がそうでした)
    ちなみに技術的な問題として、ブックを跨ぐ処理を考えておられる場合、ブックオブジェクトも捕捉して、明示してrangeを指定してやらないと、意図しない動作になります。
    こんな感じがいいと思います

    ```vba
    Set NewBook = Workbooks.Add(xlWBATWorksheet)
    BaseSheet.Copy After:=NewBook.Worksheets(1)
    Set TargetWS = NewBook.ActiveSheet
    ```
    質問者様が、別ブックへの出力を考えておられようでしたので、この形にさせていただきました。

    キャンセル

+1

範囲をコピーしておいて何やかんやするよりも次のようにしてみてはいかがでしょうか。

  1. テンプレートシートを別名で複製
  2. 複製したシートを編集
  3. 編集したシートを別ブックに移動(コピー?)
  4. コピーした場合は複製したシートを削除

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/01/29 15:16

    出力されるファイルが数百という場合における処理速度が、
    シート複製、シート削除の処理分余計にかかってしまうということで、
    その方法では行わないという方針になっています。

    記述漏れ申し訳ありません。

    キャンセル

  • 2018/01/29 16:31

    方針でそうなっているのであれば仕方ないですが、画面の更新をオフにして処理すればそれほど時間的な負担にはならないと思いますけどね。
    一番いいのは、両方のパターンを作ってどちらがよいかを決めることです。
    私が提案した方がそうでない場合に比べて数秒程度の遅れであるなら、作りこみがシンプルな方を採用したほうが余計なバグを仕込む可能性が少なくなるというメリットがあります。
    圧倒的な速度差があるなら私の案は却下ですがw

    キャンセル

+1

使える場面が限られますが、以下のようにValueを取得・適用すると、書式データ込みで情報を取得・適用することが出来ます。

XlRangeValueDataTypeは省略できます。

'保存
Dim rngDataXML As String
rngDataXML = initRange.Value(XlRangeValueDataType.xlRangeValueXMLSpreadsheet)

'復帰
initRange.Value(XlRangeValueDataType.xlRangeValueXMLSpreadsheet) = rngDataXML

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/01/30 11:49

    こちらは便利ですね!
    書式コピーも考えていたので助かります。

    キャンセル

0

Range("InitDataRange") = initRange


これだと書式などは対象にならなかったと思います。

コピーメソッドならどうでしょう。

initRange.Copy Range("InitDataRange")

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/01/29 15:09

    ありがとうございます。
    罫線に関しては、参考のURLのようにコピーするよりは、
    罫線を再設定するほうが楽そうなので、対処方法としては自前のプログラムで罫線設定することにしました。

    ちなみになのですが、セルの条件書式について、
    削除方法と、初期状態のセル書式を再設定というような方法はありますでしょうか。

    キャンセル

  • 2018/01/29 15:11

    それとも .Copyは[書式のコピー]なので、セルの条件付き書式についてもコピーされるのでしょうか。

    キャンセル

  • 2018/01/29 15:20

    条件付き書式もコピーされたはずです。
    条件付き書式の設定については、以下参考に
    https://www.tipsfound.com/vba/07020
    まあ、楽なのはテンプレート作っておいてコピーでしょうけど。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 89.96%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる
  • トップ
  • VBAに関する質問
  • VBA セルの初期状態を保持して置いて、処理後にその情報をもとにセルデータを元に戻したいです。