• ベストアンサー

VBAのオブジェクトの値を保持しておくには

ExcelのVBAにおいて、Deleteメソッドを使用して、 オブジェクトを削除する場合に、削除前に保持データを丸々待避させる よい方法はないでしょうか。 例)グラフタイトルのフォントスタイルを書き戻す。 1. ActiveChart.ChartTitle.Fontの内容を待避させる。 2. Deleteでタイトルを消す。 ActiveChart.ChartTitle.Delete 3. 間に種々処理を行う。 4. 新しいタイトルをつける。 ActiveChart.HasTitle = True ActiveChart.ChartTitle.Characters.Text = "foo" 5. ActiveChart.ChartTitle.Fontの内容を新しいタイトルに適用する。 プロパティーを列挙して変数に格納する方法を試したましたが、 プロパティーの数だけコードを書かなければならないので断念しました。 通常の変数であれば、 1. 規定値をセット(A=1) 2. 退避用の変数にAを保持させる(B=A) 3. Aに対して操作を行う 4. 待避した値をAに書き戻す(A=B) というようなことができるのですが。 オブジェクトにSet等を試しましたが、Setを使ってオブジェクトを入力した場合、 もとオブジェクトの変化に対して動的に値が変化するため、待避できませんでした。 どなたか、わかる方がいらっしゃいましたら、よろしくお願いいたします。 使用環境 WindowsXP SP2 Excel 2002 SP3

質問者が選んだベストアンサー

  • ベストアンサー
noname#221368
noname#221368
回答No.1

>Setを使ってオブジェクトを入力した場合、もとオブジェクトの変化に対して動的に値が変化  そうなんですよね~。オブジェクトの代入は、オブジェクト・アドレスの参照渡しになって、値コピーを行ってくれません。これがVB.NETであれば、CopyやCloneメソッドがあるので、値コピーを行えますが、VBAはVB6仕様なので、恐らくCopyやCloneメソッドの類はありません。 (でも調べて下さいね。そして見つかったら、教えて下さい^^) >プロパティーを列挙して変数に格納する方法を試したましたが、プロパティーの数だけコードを書かなければならないので断念しました  私は今まで、これでやって来ました。ただしプロパティーCopy用のClassをつくり、一回作れば、目的のObjectを与えるだけで、Copyから再Copyまで全てやってくれるようにしています。またCopyするプロパティーは必要最小限に抑えています。Classであれば、拡張も容易ですし、ExcelのClassを部品として再利用できます。  注意点としては、Excel Objectのプロパティーには、それ自体Objectであるものも多数含まれるので、Copyを行う際には、Objectの最下層プロパティーまで遡って、値型(StringやInteger,Singleなど)のプロパティーを退避させる必要のある事です。

_WaSaBi_
質問者

お礼

回答ありがとうございます。 回答の中に書かれている.net関係の参照設定を加えて、 Cloneメソッドをオブジェクトブラウザで探してみましたが、 やっぱり見つかりませんでした。 書かれているように Property Let/Getあたりをつかって、一個一個、 値をコピーするしかなさそうですね。

その他の回答 (2)

  • pulsa
  • ベストアンサー率57% (34/59)
回答No.3

すでに具体的な回答が出てるし、質問から日もたってるので、経験談を グラフでは自分もハマった事があって、そのときは退避用にBookを作って、そこにシートごと退避 再利用時は退避したBookからシートごとコピーしてコピーしたものを貼り付けた時点で、Setして利用しました グラフ付きのシートはコピー回数に制限がある為、思いの他苦労したのを覚えています グラフだけコピーすると勝手にリンク張っちゃうしね…

_WaSaBi_
質問者

お礼

回答ありがとうございます。 たしかに、一回シートとして待避させたほうが、理解しやすいと思います。 是非、試してみたいと思います。 なかなか、軸ラベルのタイトル名とフォント一式のみとか、 それだけをコピーする方法もなく、結局先にアドバイスしていただいた方法で現在は作業を進めています。

noname#221368
noname#221368
回答No.2

>Property Let/Getあたりをつかって・・・  ヘルプに正直な方ですね。  Classにおいて、Property Let/Getを使うのは、Property値入出力時に値を検査できるから、推奨されているに過ぎません。今回は外部に公開予定もないと思いますので、Property Let/Getは省略してもいいと思います。以下では、Public Class ~ End Class で、Classファイルを表します。 Public Class Ob_j  x as Single  s as String End Class だけで、クラス Ob_j には Property x,s が定義されます。 Dim Obj as New Ob_j Ob_j.x = 1.0 Ob_j.s = "OK" なんて事ができます。私はたいてい Property Copy 用の Class に、Sub Copy_Constractor と Property_Copy Function を設けます(名前はどうでも良いです)。例えば、Chart Object が T型(Object型)の Property SingleString を持ち、SingleString がさらに、Single型の x と String型の s を持つとしたら、 Public Class Chart_Copy  Private SS as New T Public Sub Copy_Constractor(ByVal Target as Chart)  With Target   With .SingleString    SS.x = .x    SS.s = .s   End With  End With End Sub Public Function Property_Copy(ByVal Target as Chart) as Chart  With Target   With .SingleString    .x = SS.x    .s = SS.s   End With  End With End Function としています。

_WaSaBi_
質問者

お礼

最近、忙しくマクロを試す暇がなかったので、 返信遅くなり、申し訳ありません。 確かに、今回の場合Let/Getは使わないですね。すみません。 アドバイスにしたがって、とりあえずFontとCharactersをコピー&ペーストするマクロを書いてみました。 やっぱり、プロパティーの列記はめんどくさいですね。

関連するQ&A

  • オブジェクトに値を保持させるにはプロパティに追加ですか?

    オブジェクトに値を保持させるにはプロパティに追加ですか? 新たなプロパティを作成してそこに保持する方法でいいですか? ほかのやり方がありますか?

  • VBAでオブジェクトのプロパティの値を変えたい

    エクセル2010のマクロの話なのですが、 添付画像にある、オブジェクトの「Value」というプロパティーの値を変更するための文法がわかりません。  PsyBcLbll.Value=13342353654 という感じで書いているんですが, たしか、 「変数が宣言されていない」 とかいうエラーが出てうまくいきませんでした。 一体、どう書けばいいんでしょうか?

  • ExcelのVBAの保護をかけた時のグラフについて教えてください。

    グラフにタイトルを設定した後、保護をかけると「ChatクラスのHasTitleプロパティを設定できません」といわれてしまい、.HasTitle=Trueで止まってしまいました。シートの保護をかけても動くようにしたいのですが、どうしたらよいのでしょうか。 (保護しなければ通常に動きます。) 'グラフをオブジェクトで配置 set chartObj=worksheets("Sheet1").ChartObjects.Add(200,0,300,200) chartObj.Chart.SetSourceData Worksheets("Sheet1").range(range("b4").End(xlDown),ActiveCell.end(xlToright)) 'タイトルをつける with worksheets("Sheet1").ChartObjects(1).Chart .HasTitle=True .ChartTitle.Text="タイトル" End with 保護をかけてもグラフの作成ができるのに、タイトル部分で止まってしまうのはなぜでしょうか。 よろしくお願い致します。

  • VBA 実行時エラー1004 rangeメソッドは失敗しました。globalオブジェクトのエラー

    始めまして、VBA初心者のものです。 ただいまエクセルでグラフを作成しています。作業自体は単純作業の繰り返しなのでVBAを用いてやりたいのですが、マクロを実行したときに実行時エラー’1004’rangeメソッドは失敗しました。’_global’オブジェクトとメッセージが出て、実行できません。 デバックをすると以下の5行目で黄色のバーが出ていました。自分なりに原因を考えたのですがrangeの関係するところに、Range("A8:A1587,e8:e1587")というような変数を用いないやり方でやると上手くいくので、変数に関する定義がまずいと思うのですが、それ以上の事は分かりません。どなたか、分かる方がおりましたら、よろしくお願いします。また、プログラムは以下のようになります。 Sub 繰り返し() '繰り返し Dim s As Integer For s = 0 To 17 Range("cells(8,1):cells(1580,1),cells(8,s+2):cells(1580,s+2)").Select Range("cells(8,s+2)").Activate Charts.Add ActiveChart.ChartType = xlXYScatter ActiveChart.SetSourceData Source:=Sheets("20081216_210647").Range( _ "cells(8,1):cells(1580,1),cells(8,s+2):cells(1580,s+2)"), PlotBy:=xlColumns ActiveChart.SeriesCollection(1).Name = "=""0810p2x""" ActiveChart.Location Where:=xlLocationAsNewSheet, Name:="0810p2x" With ActiveChart .HasTitle = True .ChartTitle.Characters.Text = "0810p2x" .Axes(xlCategory, xlPrimary).HasTitle = True .Axes(xlCategory, xlPrimary).AxisTitle.Characters.Text = "t" .Axes(xlValue, xlPrimary).HasTitle = False End With Next End Sub

  • なぜiは変数の値が保持されるのに、wは保持されない

    なぜiは変数の値が保持されるのに、wは保持されないのでしょうか? Sub test() Dim w As Worksheet Dim i As Long i = 1 For Each w In Worksheets i = i + 1 Next MsgBox i MsgBox w.Name End Sub -------------------------------------- を行うと、 MsgBox i は表示されるのに、 MsgBox w.Name は、 「オブジェクト変数または With ブロック変数が設定されていません。」になります。 wはオブジェクト変数だから、 For Each ステートメントを抜けると値が破棄されてしまうのでしょうか? でもvbaのヘルプの 「For Each...Next ステートメントの使い方」 を見ても 「ステートメントを抜けるとオブジェクト変数なら値が破棄されます」 と記載されていません。

  • エクセルVBAの質問

    VBAでわからないことがあります。 まず下記のプログラムをご覧下さい。 グラフを作成して、そのグラフにタイトルをつけるというものですが、グラフを削除してまた新たに作成すると "graph1"ではなくなりますよね? グラフの番号がどのようになっても利用できるプログラムを作成したいのですが、どのようにすればよいのでしょうか? ************************** Sub MakeChart() Dim mySouce As Range Set mySouce = Range("B2").CurrentRegion Charts.Add ActiveChart.SetSourceData _ Source:=mySouce,PlotBy:=xlColumns Charts("Graph1").Activate with activechart .HasTitle=True .ChartTitle.Text = "4月度売上高" End Sub ************************* 私が考えたのは Charts("Graph1").Activate ⇒chart("graph" & charts.count) だと思うのですが、うまくいきませんでした。 ご存知の方がいましたら、教えていただけないでしょうか。

  • グラフのタイトルにセル内の文字列を使うには?

    Excelにて、InputBoxで入力された数の行を参照して、 グラフを生成するマクロを以下のように作成しています。 データの範囲は以下のようにInputBoxでの入力された数値を使って 処理できたのですが、タイトルが上手く処理できません。 入力された数値を利用して、値を参照するセルの位置を決定し、 そのセルに入力されている文字列を .ChartTitle.Characters.Text の値として代入したいのですが どう記述すればいいのでしょうか? 以下のように(抜粋)、セルの範囲を一旦変数titleRangeに代入し、 .ChartTitle.Characters.Text = "=Sheet1!" & titleRange と記述して、セル内の文字列を参照させたかったのですが、 文字列として、シート名と変数名がそのまま表示されてしまいます。 初心者なので、分かりにくい説明で申し訳ありませんが、 グラフのタイトルに指定したセル内の文字列をセットする 方法を教えていただけないでしょうか? colNum = InputBox("対象行") titleRange = "R" & colNum & "C1" With ActiveChart   .HasTitle = True   .ChartTitle.Characters.Text = "=Sheet1!" & titleRange End With

  • 変数に保持している値はどうやったら確認できるの?

    Publicで宣言した変数はブックを閉じるまで値を保持すると言うけど、 その保持している値はどうやったら確認できるのですか? 例えば標準モジュールに ++++++++++++++++++++++++++++++ Option Explicit Public a As String Sub test() a = "こんにちは" End Sub ++++++++++++++++++++++++++++++ とした場合、 1回testを実行すると、a には "こんにちは"が入りますよね。 この時例えばトイレに行って、パソコンの前に戻ってきたときに、 「aに何の値がはいってたっけ?」ってどうやって確認すればいいのでしょうか? testを実行する前に、ウォッチ式にaを登録しましたが、 testを実行し終わるとaの値は「対象範囲外」になっています。 でもこの状態でもaの値は保持されてるのですよね? 発見したのは、testをF8でステップインをすると、 2行目のa = "こんにちは"を通過する前に、aにすでに値が入ってる事がわかりました。 こういう方法で確認するしかないのでしょうか?

  • VBAでオブジェクト変数にsetしたシートがactiveかどうかを調べるには?

    標準モジュールの冒頭でワークシート用のオブジェクト変数を確保し、 あるタイミングで、あるシートをそのオブジェクト変数にSetしています。 で、そのシートに値をセットするときに、そのシートがActiveだった場合だけやりたい処理があるのですが、Setしてあるオブジェクト変数だけを見てそのシートがActiveか否かを判断する方法って、あるのでしょうか。 コード例) Private oSheetA as Worksheet Sub SetSheet(sName as String)   Set oSheetA = worksheets(sName) End Sub Sub SetValue(nValue as integer)   xxxxxx ←ここでoSheetAがActiveならやりたいことがある。   oSheetA.Cells(nRow, nCol) = cValue End Sub 具体的には、複数のBookを開いている状態で、Activeシートが何であるかはオペレータの操作次第なので固定化できない状態で、SetValueが呼び出されたとき、oSheetAがActiveだったら、値をセットするセルが見えるようにセルをActivateかスクロールさせたいんです。

  • メールフォームの値保持

    メールフォームを作成しているのですが、値をセッションにて保持したいのですが上手くできません。 考え方が誤っているような気がするので、指摘いただけないでしょうか。どうかよろしくお願いします。 以下のような3画面移動で、値を保持したいのです。 入力==================================================================== <html><head><title>入力</title></head> <body> <form action="confirm.php" method="post"> 魚は好きですか?<BR> はい<input type="radio" name="fish" value="yes"><BR> いいえ<input type="radio" name="fish" value="no"><BR><BR> <input type="submit" value="送信"> </body> </html> 確認==================================================================== <?php session_start(); $fish = $_POST["fish"]; $_SESSION["fish"] = $fish; ?> <html><head><title>テスト確認画面</title></head> <body> <?php print("変数fishの値は".$_SESSION["fish"]."です。"); ?> <form action="output.php" method="post"> <input type="submit" value="次ページへ値を渡す"> </body> </html> 完了==================================================================== <?php session_start(); ?> <html> <head><title>テスト完了画面</title></head> <body> <?php print("変数fishの値は".$fish."です。"); ?> </body> </html>

    • ベストアンサー
    • PHP