[[20140528144517]] 『既存の図形テキストボックスの内容を変える。』(欲張り爺) ページの最後に飛ぶ

[ 初めての方へ | 一覧(最新更新順) | 全文検索 | 過去ログ ]

 

『既存の図形テキストボックスの内容を変える。』(欲張り爺)

 (例)現在のテキストが【はい】だったら⇒【いいえ】としたいのです。

 フォーム上のテキストボックスと異なり操作(プロパティー)が解りません。
 ActiveSheet.Shapes("Btn").TextFrame2.TextRange.text="新テキスト"
 ActiveSheet.Shapes("Btn").TextFrame2.TextRange.Characters.text="新テキスト"
 などと試行しましたがエラーばかり・・・

 私の中ではシート上に沢山のマクロ設定ボタンを並べたくは無く、1つのボタンをトグル
 させて画面をすっきりさせたいのです。

 因みに、TextFrame、TextFrame2の違いは何でしょうか?

< 使用 Excel:Excel2013、使用 OS:Windows8 >


 マクロの記録でヒントになるコードが生成されませんか?

 私は、素で書けるコードは、

 Sub test()
        With ActiveSheet
           With .TextBoxes.Add(10, 10, 100, 20)
              .Text = "文字を入力"
           End With
        End With
 End Sub

 Shapeオブジェクトからだと

 Sub test2()
        With ActiveSheet
           With .Shapes.AddTextbox(msoTextOrientationHorizontal, 10, 35, 150, 20)
              .TextFrame.Characters.Text = "TextFrameを使って文字入力"
           End With
        End With
 End Sub

 >TextFrame、TextFrame2の違い

 私もそんなによく調べていませんが、
 Shapeオブジェクトのテキストフレームを操作するTextframeにはない機能を
 別オブジェクトとして追加したのだと思います。

(ichinose) 2014/05/28(水) 17:29


 ichinoseさんへ 有難うございます。

 最初にマクロの記録を利用したコードがエラーの原因と考えていましたが、それは 全くの見当違いでした。
 その原因とはテキストの変更と共に別のプロシージャを走らせていた事でした。
 プローシージャの中の保護を懸ける部分が『システムエラーです…』等となっていました。
 こんな事で質問した事を恥ずかしく思います。
 でも、1時間くらい考えても原因が掴めなかったで投稿しました。何とか本日に至り解決できました。

 以前に(昨年11月初頭)に『二つのテキストボックスの値入替』で質問しました。
 実は、未だに角田氏のコントロール配列『BPCA』が分かりません。私にとって難し過ぎるのです。
 表現方法が分から無いのですが、クラスモジュールを階層化したり、それを参照する事等。

   プロパティー作成後どの様にしてVBA上で確認するのか?
   Set Property はどうなっているのか?

 この様な事を此処で質問してもいいのでしょうか??

(欲張り爺) 2014/05/29(木) 05:22


 >沢山のマクロ設定ボタンを並べたくは無く
 これ、テキストボックスの話ではないのですね!!
 フォームのボタンの話ですか?

 ならば、

 Sub test1()
    With ActiveSheet.Buttons.Add(10, 10, 100, 40)
       DoEvents: DoEvents
       MsgBox "ボタン作成"
       .Caption = "文字を入れたよ"
    End With
 End Sub
 Sub test2()
    With ActiveSheet.Shapes.AddFormControl(xlButtonControl, 10, 70, 100, 40)
        DoEvents: DoEvents
        MsgBox "ボタン作成"
       .TextFrame.Characters.Text = "文字をTextFrameを使って入れたよ"
    End With
 End Sub

 ボタンは、文字が入力されていても Textframe2.hastext の値が Falseなので、
 このTextframe2では、管理されていないようですね

 私は、古い図形オブジェクトを可能な限り(問題がないかぎり)、使っています。
 これの方が記述が簡単なので・・・。

 ただ、Shapeオブジェクトを介さないとうまくいかないこともありますから、
 こちらのチェックも必要ですね!!

 TextFrame2もいずれは、これだけでテキストフレーム周りは操作できる主流に
 なっていくのでしょうねえ!!

(ichinose) 2014/05/29(木) 06:41


[[20131030060619]] 

 これですね!!

 スレッドを改めた方がよいかもしれませんね!!

 >未だに角田氏のコントロール配列『BPCA』が分かりません。
 >表現方法が分から無いのですが、クラスモジュールを階層化したり、それを参照する事等。
 >プロパティー作成後どの様にしてVBA上で確認するのか?
 >Set Property はどうなっているのか?

 角田さんのサイトで言う疑似コントロール配列のしくみ これが理解できますか?

 これの理解をすることが先決です。プログラムの構造的な問題はありますが、
 コントロール配列のしくみを理解するならまずここです。

 表現方法のわからない点などもそうですが、
 Set Propertyについても、 もう少し詳しく疑問点を記述してください
 分からない点がどこなのか が私に理解できていませんので・・・。

(ichinose) 2014/05/29(木) 09:47


 有難うございます

 >スレッドを改めた方がよいかもしれませんね!!
   BPCA について5章までは比較的容易に理解出来ました。然し、それ以降は一気にハードルが高くなり
   内容把握が出来ませんでした。
   サイト…k窓にも類似したコントロール配列についての記述が有り、勉強を兼ね同時に読んでいました。
   BPCAでは結果的には以下の『 Rgst メソッド』の意味が理解出来ませんでした。

 'コレクションに載せたコントロールをクラス登録して配列化
 '(引数で発生させるイベント種別を受け取る)
 Public Sub Rgst(ByVal NewEvent As Long, Optional ByVal AllType As Boolean = False)
 Dim i As Integer
 Dim blnERR As Boolean
   If (blnRgst = True) Then
       '実行済み
   ElseIf (colBpcaCtrlGrp.Count = 0) Then
      blnRgst = False
   Else
      blnAllType = AllType
      blnERR = False
      '先頭のコントロールタイプと同じ物だけOK(AllType=False時)  ←いつもFalseでは?
      MyTypeName = TypeName(colBpcaCtrlGrp(1))
      For i = 2 To colBpcaCtrlGrp.Count
         If (MyTypeName <> TypeName(colBpcaCtrlGrp(i))) Then
            If (blnAllType = False) Then
                blnERR = True
            End If
       :
       :
 つまり、ここから先が理解出来ないのです。
 体系的にメソッド・プロパティー・メンバーの繋がりがどの様になっていくのか分かりません。
 基本を知らずして質問しているようです。 
 私の様なレベルの者に対する相応なスレをご紹介ください。 

 ※Set Property(これはk窓の中で記述されている)…ヘルプではインプリメントが…→??

(欲張り爺) 2014/05/29(木) 11:17


 追記

 疑問点のいつも[False]では? → [True] でした。

(欲張り爺) 2014/05/29(木) 11:41


 このサイトを紹介しておいて、申し訳ないのですが、
 提示されたコードはどこで見ることが出来るのですか?
 出来れば、リンクを貼ってください。続きのコードが見たいので・・・。
 私には、見つかりませんでた。

 が、おそらくは、Addメソッドで登録したコントロールのイベントが拾えるように
 それぞれのコントロールのタイプを調べて設定しているのでしょうねえ!!
 つまり、この後に記述されているコードがないとイベントが発生しないことになります、たぶん。

 AllTypeは、省略すると、Falseですが、Trueと指定すことも出来ますから、
 常にFalse という事ではありませんよ!!

 Set Propertyは、Setステートメントを使って、
 オブジェクトを登録するプロパティを作成するときに使います。

 Class1にProperty Setを使って、Rangeオブジェクトを登録する例と

 Class2にProperty letを使って、Rangeオブジェクトを登録する例を記述します。

 Class1とClass2というクラスモジュールを作成してください。

 Class1のモジュール

 Option Explicit
 Private crng As Range
 Property Set r(rng As Range)
 'オブジェクトの登録に Property Setを使う 
    Set crng = rng
 End Property
 Property Get r() As Range
    Set r = crng
 End Property

 Class2モジュールに

 Option Explicit
 Private crng As Range
 Property Let r(rng As Range)
 'オブジェクトの登録にProperty Letを使用する
    Set crng = rng
 End Property
 Property Get r() As Range
    Set r = crng
 End Property

 標準モジュールに

 '=============================================
 Sub test()
    Dim cls1 As Class1
    Dim cls2 As Class2
    Set cls1 = New Class1
    Set cls2 = New Class2
    Range("a1").Value = "ルパン?V世"

    Set cls1.r = Range("a1")
    MsgBox cls1.r.Value

    cls2.r = Range("a1")
    MsgBox cls2.r.Value

    Set cls1 = Nothing
    Set cls2 = Nothing
 End Sub

 testのコードを見てもらうとわかりますが、

 cls1では、プロパティ r にセルA1を登録するのに

 Set cls1.r = Range("a1")  とSetステートメントを使っているのに対し、

 cls2では、プロパティ r にセルA1を登録するのに

 cls2.r = Range("a1")  とSetステートメントなしでもオブジェクトの登録が出来てしまいます。

 結果、どちらも正しく登録できていることは確認できます。

(ichinose) 2014/05/29(木) 22:48


 このコードは『擬似からの脱却』第10章の『clsBpcaCmd モジュール(1段目)』に有ります。
 又、実際に掲示しているコードは、汎用クラス【clsBPCA】(Zipファイル)の中に有ります。
 前述した通り第5章までは私なりにゆっくり時間をかけて理解しましたが、この章では一気に
 難しくなったのです。
           リンク先 http://www.h3.dion.ne.jp/~sakatsu/index.htm

 前述した通り第5章までは私なりにゆっくり時間をかけて理解しましたが、この章では一気に
 難しくなったのです。

 Property Set について
  Rangeオブジェクトをクラスの中でProperty Setを使い登録し利用している事は理解しました。
  Property LetでRangeオブジェクトを登録するのと同じ役割なのでね。

 良く分かりませんが同じ役割をする物が何故2個もあるのかと疑問に思います。Property Letの方が
 使い勝手が良いように思いますが・・・

 どうも有り難うございました。又、ゆっくり取組みます。
(欲張り爺) 2014/05/30(金) 12:00

 >第10章の『clsBpcaCmd モジュール(1段目)』に有ります

 >実際に掲示しているコードは、汎用クラス【clsBPCA】(Zipファイル)の中に有ります

 これ、パスワードかかっていませんか?

 共通で確認できるのは、

  >Public Sub Rgst ( )
  >Dim i As Integer
  >    If ( blnRgst = True ) Then
  >        '実行済み
  >    ElseIf ( colCtrl.Count = 0 ) Then
  >        blnRgst = False
  >    Else
  >        ReDim clsCtrlCh ( 1 To colCtrl.Count )
  >        For i = 1 To colCtrl.Count
  >            Set clsCtrlCh ( i ) = New clsBpcaCmdCh    ' インスタンスの生成
  >            With clsCtrlCh ( i )
  >                .Item = colCtrl ( i )
  >                .Index = i
  >                .Parent = Me
  >            End With
  >        Next i
  >        blnRgst = True
  >    End If
  >End Sub

 これはコマンドボタンのクリックイベントのみの例ですが、コントロールやイベントの数が増えても
 基本は同じだと思います。

 特に

  >        ReDim clsCtrlCh ( 1 To colCtrl.Count )
           '↑配列をADDメソッド登録したコントロール数だけ宣言
  >        For i = 1 To colCtrl.Count 'コントロールの数だけループ
  >            Set clsCtrlCh ( i ) = New clsBpcaCmdCh    ' インスタンスの生成
  >            With clsCtrlCh ( i )
  >                .Item = colCtrl ( i ) ’対象コントロールをセット
  >                .Index = i             'Indexを設定
  >                .Parent = Me           ’clsBpcaCmdChが呼び出しする時のオブジェクトを指定
  >            End With
  >        Next i 

 この部分でしょうか?

 ADDメソッドでコレクションcolCtrlに登録されたコントロールを実際にクリックイベントが
 発生するようにclsBpcaCmdCh オブジェクトに登録している処理が上のコードです。

 >良く分かりませんが同じ役割をする物が何故2個もあるのかと疑問に思います

 実際には、Property Letは、オジェクト以外の数値や文字列などを登録する場合が多いと思います。

 >Property Letの方が使い勝手が良い 

 コードを書く場合は、良いですけどね!!

 誰かが書いたそのコードを読む場合には、

 cls2.r = Range("a1")

 と記述されると、プロパティrは、セルA1の既定のプロパティであるValueを代入しているかもしれない
 なんて、疑問に感じてしまいます。Property Letの中のコードをみて納得するのでは読みにくい
 という事になってしまいます。

 Set cls1.r = Range("a1")

 こっちの方がわかりやすいと思いますけどねえ VBでは、Setステーメントがないのでその練習という
 考えから Property Let という見方も出来ますけど、VBAでは、

 Property Set です、私は・・・。

(ichinose) 2014/05/31(土) 00:29


コメント返信:

[ 一覧(最新更新順) ]


YukiWiki 1.6.7 Copyright (C) 2000,2001 by Hiroshi Yuki. Modified by kazu.