[[20151103144805]] 『定数(const)の変更』(まさっち) ページの最後に飛ぶ

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

 

『定数(const)の変更』(まさっち)

publicで指定している定数に対して、変更をかけることは可能なのでしょうか?
可能ならば色々捗ると思いまして。。。

vbeの操作関連でも構わないので、一番単純な変更方法があればご教授願います。。
よろしくお願いします。

< 使用 Excel:Excel2007、使用 OS:Windows7 >


宣言の部分を変更すればいいのでは?

例えば、「test」という変数があった場合、

Public const test As Integer


Public test As Integer

のように…。

違うかな?
作成者が意図して定数としているので変更すると問題があるかも
しれないけどね。
(K) 2015/11/03(火) 15:45


Kさん
言葉足らずで申し訳ありません。
「定数」という定義そのものというよりも
定数として指定している「値」に対して変更をかけたいのです。。

Public Const i As Long = 10
↓(処理を実行)
Public Const i As Long = 11(任意の値に変更)

イメージとしてはこのような感じです。
(まさっち) 2015/11/03(火) 16:09


 今は定数になっているけど、これを変数にして、ケースによって別の値をセットしておきたいということですか?

 そういうことであれば

 Public i As Long

 こうしておけばいいのですが?

 ただし、ある処理までは 10 のまま ということを言っておられるようですから
 Workbook_Open あたりで i = 10 としておくことがいいでしょうね。

 いずれにしても パブリックであろうがそうでなかろうが、定数の値を動的に変更するのは不可能です。

 ただ・・・・ひとそれぞれですから、あぁしろこうしろとは言いにくい部分ですが
 パブリック変数というのは、実に厄介なものです。できれば使わないほうがいい。
 ましてや、ある場合はこう、あるばあいはこう と値を変えるなら、それは定数ではないでしょう。

 どんな目的でどんな時にどのように使いたいのかを説明されれば、全く別のアドバイスも
 皆さんから寄せられるかもしれませんよ。

(β) 2015/11/03(火) 16:43


 すでに指摘がありますので、大いなる蛇足です。

定数というものは、そのように、後から変更できないようにするのが目的で
作られたものです。

 単なる変数だと、
 ・複数の人が拘わっている場合に、意図的に変更されてしまうとか、
 ・単独で作成していても、間違って上書きしてしまう
 リスクがあり、こうしたことを防ぐために定数はあります。

 ですから、変更したいのであれば、定数ではなく変数にすべきです。

 # 余談ですが、言語によっては、変数そのものが原則 immutable(書換えできない)である
 # というようなものもあります。
 # じゃあカウンタ用変数とか、累計を求めるにはどうするんだというと、
 # 原則として再帰を使うのだそうな。

(γ) 2015/11/03(火) 17:35


 >言語によっては、変数そのものが原則 immutable(書換えできない)
 Constで宣言した名前、実はこれかもしれませんよ!! C言語のConstからの類推です。

 実際にオフコン時代にもこのような変数が扱える言語で開発を行っていました。

 変数と言ったって 実質定数と同じ扱いでした。

 違いは、宣言した名前にアドレスが付けられていたことです。
 ですから、アドレスのある個所に実際のデータがあるという仕組みです。

 しかし、そのアドレスのある個所は、プログラムコードが書かれているメモリと同じ性質のメモリ上にデータがあるのです。つまり、書き換え不可のメモリなのです。
 昔は、コンパイル後の実行ファイルにパッチというものをあてるためにコード領域を空けておくためにも
 使用していました。

 以前は、Constは、コンパパイル時に実定数に書き換えられるしくみものと思いこんできましたが・・・。

 Constを使ってリテラル値に名前を付けるのは、コード分かりやすくするためです。
 Const 男=1
 Const 女=2

 ・
 ・ 

 dim sex as long

 if sex=1 then

 とするより、

 if sex=男 then

 とする方がわかりやすいということです。

 既に投稿があるように値を変えたいなら 変数にすることですが、Enum定数とからませる方法も検討してください。

 Option Explicit
 Enum 性別
   男 = 1
   女 = 2
 End Enum
 Sub test()
    Dim Sex As 性別
    Sex = 男
    If Sex = 男 Then
       MsgBox "Man"
    Else
       MsgBox "Woman"
    End If
 End Sub

 >パブリック変数というのは、実に厄介なものです。できれば使わないほうがいい。
 これは、私も原則 同意見です。

(ichinose) 2015/11/03(火) 18:35


 テーマとは関係のない余談どころか脱線ですが、懐かしくなりまして。

 >>昔は、コンパイル後の実行ファイルにパッチというものをあてるためにコード領域を空けておくためにも使用していました。

 社会人になって最初にあてがわれた環境がメインメモリー16K (!!!!) という、それでも当時はオフコンといわず堂々たる電子計算機。
 言語はアセンブラーでしたが、ソースコードをカードで読み込ませ、アセンブルして、結果の実行モジュールを、これまたカードにヘキサパンチしたもので出力。
 ちょっと長めのコードですと、アセンブル完了までに3〜4時間かかるのはザラ。

 コード変更があれば、もちろん、ソースコードを直して再アセンブルが筋ですが、時間がもったいないので、ichinoseさんがいわれるパッチ用のカードを
 出力された実行モジュールカードに追加していました。
 これは、機械語になった、その部分を置き換えるんですが、その機械語として存在する桁数内でしか変更ができないわけで、そのために、やばそうな所には
 そういった、からっぽの領域をいくつか埋め込んでおいて、その空っぽの領域に機械語を直にセットしたりしていましたねぇ。

 いやいや、年寄りの、何の意味もない繰り言でした。
 失礼しました。

(β) 2015/11/03(火) 20:31


「オートシェイプを作成する」といった処理があるとします。
その処理で作成するオートシェイプの
「線の太さ」や「塗りつぶしの透明度」などの情報は、パブリック定数として指定しておきます。

その「線の太さ」や「塗りつぶしの透明度」などの情報を書き換えるための処理を
考えているところです。

現状、塗りつぶしの色ごとに簡単なマクロを複数作っているのですが、
線の太さも考慮しなければならなくなり、
「任意に変更できる定数」を参照すれば、
ややこしい処理や同じような複数のコードを書かなくて済むかな?と
考えたのがこの質問を投稿した動機です。

こういった動機は無駄な情報かと思いましたが、書いたほうがよさそうですね。
色々と言葉足らずで申し訳ありません。

もちろん、これにかわる代替案があればそちらを参考にしたいと思います。
よろしくお願いいたします。

(まさっち) 2015/11/03(火) 23:30


(1)
処理を通じて、同じ数値を使うということなら、
よくやるのは、
Public Const i As Long = 10
'''Public Const i As Long = 11
と二つならべておいて、どちらかはコメントアウトするという方法です。

(2)
処理Aでは 10
処理Bでは 11
と、同じ定数で使い分けたい、ということですか?

「任意に変更できる定数」という言葉からはそのような意図のようですが。
それは日本語として言語矛盾です。
定数とは、定まった数なんですから、任意に変更できるものを定数とは
呼びません。 Const ステートメントも、その感覚と全く同じです。

その場合は、定数を二つ定義して、処理A、処理Bでスイッチすることになるでしょう。
もしくは、既に皆さんから指摘があったように、
定数ではなく変数を一つ使って、途中で更新するかです。

(γ) 2015/11/03(火) 23:53


 処理そのものはほとんど同じで一部の条件(WeightであったりTransparencyであったり)だけが異なる場合
 こんなコードにすることが多いですね。

 Sub 処理1()
    Call 実際の処理(5, 0.3)
 End Sub

 Sub 処理2()
    Call 実際の処理(1, 0.1)
 End Sub

 Sub 実際の処理(wgt As Long, tp As Double)
    '線の太さ wgt  透明度 tp を使って処理
    MsgBox wgt & vbLf & tp
 End Sub

(β) 2015/11/04(水) 00:24


 私ならシートを一つ.Visible = xlVeryHiddenで隠しておいて、書き換えられるようにしておきますかね・・・
 そうすれば書き換えられることもないだろうし、保存すれば次回はそこからスタートになるし便利だと思いますけどね!
(稲葉) 2015/11/04(水) 08:36

>>「オートシェイプを作成する」といった処理があるとします。
>>その「線の太さ」や「塗りつぶしの透明度」などの情報を書き換えるための処理を
>>考えているところです。

上記の内容から察するにパラメータの置換ですね。

私だったらパラメータの部分を変数にして、実行前に代入します。
処理の起動方法にもよるので、一例だけ。

マクロ名で選択する場合です。

'変更したいパラメータの変数を定義
Public line_wide As Long
Public transparency As Long

'線の太さが「10」のオートシェイプ
Sub test1()

  line_wide = 10
  transparency = 0.5

  make_AutoShape(1)

Ebd Sub

'線の太さが「11」のオートシェイプ
Sub test2()

  line_wide = 11
  transparency = 0.5

  make_AutoShape(2)

Ebd Sub

'オートシェイプを描画する処理
Sub make_AutoShape(flg As Integer)

  'flgによって形状を変えることも可能。
  'もし、必要がない場合でも引数を定義しておくとマクロ名が表示されない。

Ebd Sub

こうすると
マクロ名には「test1」「test2」しか表示されないですし、
何のパラメータが違うのかもわかりやすいと思います。

以上、参考にしてください。

(K) 2015/11/04(水) 10:18


こんにちは。

> 「オートシェイプを作成する」といった処理
をサブプロシージャにする。
「線の太さ」や「塗りつぶしの透明度」などは、optionalな(省略可能な)引数として与える。
引数省略時の規定値を、そのパブリックな定数の値とする。

というのはどうでしょう。

( 佳 ) 2015/11/04(水) 19:40


 佳さんの提言を私のコードに当てはめるなら

 Public 定数 宣言をすべてなくして

 Sub 実際の処理(Optional wgt As Long = 5, Optional tp As Double = 0.3)
    '線の太さ wgt  透明度 tp を使って処理
    MsgBox wgt & vbLf & tp
 End Sub

 と記述。この 5 や 0.3 が、Public定数として規定しようとしていた値。

 使う場合は 変更したい引数のみを指定。指定のない引数は、あらかじめ定められたデフォルトになります。

(β) 2015/11/05(木) 18:50


コメント返信:

[ 一覧(最新更新順) ]


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