[[20030911104503]] 『VBA:行を変数にて指定するには』(よ) ページの最後に飛ぶ

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

 

『VBA:行を変数にて指定するには』(よ)

とても初歩的な質問ですが、すみません。

VBAで行を指定する時は Rows("1:2").Select とすると思いますが、この行数を変数にした場合、どのように表記すればいいかわからず困っています。

例えば、Rows("r1:r2") とするとエラーになります。どのように記述したらよいですか?教えてください。


 Dim R1 As Long
 Dim R2 As Long
  R1 = 1
   R2 = 2  
   Rows(R1 & ":" & R2).Select

 変数は""で囲みません。""で囲むとすべて文字列扱いとなります。(INA)


INAさん、さっそくありがとうございます。
無事できました。助かりました!(よ)


 [INA]さんいつもありがとうございます。

 本件はこれで解決したようですが、

 なぜIntegerではなくLongを使うのか皆さんの勉強のために説明をしてください。

(kazu)


 またまた見落としていました。 
 この場合は、文字列でも良かったですね。すみません。(_ _)

 ★間違っているかもしれないので、ここからは真剣に読まないで下さい。
  通常、文字列(String)と数値(Long,Integerなど)は、自動的に変数の「型変換」が
 行われるので、気になりませんが、
 変数にどうやって値を代入するか 及び 変数の値をどのように使うかによって
 使い分けています。
  その為、なるべくエラーの原因とならないようTypeNameで調べたりして
 型をあわせるようにしています。 
 有名な話ですが、例えばメッセージボックス(MsgBox)はヘルプで、
 「整数型 (Integer) の値を返します。」 とあります。
 戻り値は 1 〜 7 なので、 数値の範囲で考えると問題はないですが、   
 実際は、   Debug.Print TypeName(MsgBox("")) で調べると
「 Long 」 が返ってきますので、
   Dim Result As Long
   Result = MsgBox("TEST", 1)
 のように戻り値は Long で宣言しています。  
 また Integer と Long では Long の方が処理が速いメリットもあります。
 理由は省略しますが、その代わりサンプルを掲載しておきます。

  <スピード比較サンプル>
 Sub SpeedTest1()
    Dim i As Integer
    Dim j As Integer
    Dim k As Integer
    Dim t As Single
    t = Timer
    For i = 1 To 5000
        For j = 1 To 5000
            k = i + i
        Next
    Next
    Debug.Print Timer - t
 End Sub

 Sub SpeedTest2()
    Dim i As Long
    Dim j As Long
    Dim k As Long
    Dim t As Single
    t = Timer
    For i = 1 To 5000
        For j = 1 To 5000
            k = i + i
        Next
    Next
    Debug.Print Timer - t
 End Sub

     (INA)

 回答ありがとうございます。

 > TypeNameで調べたりして型をあわせるようにしています。 
 なるほど。

 私は行数とかは標準的にIntegerを使っていましたが、
 行数が32,767を超えるとあふれるので、[INA]さんは経験的に
 Longを使っているのだと思っていました。

 スピード比較サンプルを実際に実行してみました。
 これは以外な結果でした、Integerの方が早いと思っていました。

 Integer 3.828125
 Long 3.714844

 役に立つ情報をありがとう。
 (kazu)

 このスレ見ていて、自分の間違いに気付きました(汗)。

 変数の宣言って、
 Dim buf1, buf2 As Integer
 ってやると、buf1はVariant型になるんですね(汗)。
 いままでずっとそうしてましたよ。 懺悔懺悔。
 正) Dim buf1 As Integer, buf2 As Integer

 私はDOS時代からの人間なんで、16ビットでIntegerがコンパイルでも
 実行速度でも効率がいい〜 っていう頭でした。
 そういや32ビットなんですよね、もうじき64ビット出るみたいだし。
 kazeさんのベンチマーク、IntegerとLongの差があまりないですね。
 ウチの600Mhzでは2秒も差がでました。

 しかしINAさんのTypeNameで型を調べて〜 というのはちょっとビックリ。
 時代が変わったのかな〜
 昔は変数の宣言でよくコンパイラに怒られてたので気を付けてましたけど、
 VBでは怠けすぎですね。
 (ramrun)

 ちょっと待っておくんなはれ。
 私にも教えて欲しい事がおまんねん。

 何で変数の宣言って必要なんでっか?

 私はでっせ、私は勝手にこう解釈してまんねんで、えぇ。
 予め宣言するっちゅう事は「作業中に生じるメモリ不足に対して、宣言してあるメモリ
 は一切お貸ししまへんでえ、不足分はデスクトップなりなんなりでヤリクリしなはれ」
 と言う不可侵の領域を指しとると思うてまんねん。
 せやから宣言する以上、なるべくメモリ消費量の少ない型で宣言するんがマクロを組む
 上での必須条件と自覚(でけてえへん)してまんねんけどちゃいまっしゃろか?

 いいえぇな、Integerが速いか、Longが速いか侃々諤々の議論を覗きましてな、ついで
 に教えてもらえたらええなあと思うて首突っ込んだ訳なんですけど、わたしゃあんな競
 争公平やないと思いますわ、えぇ。
 せやかてそうでっしゃろ、Integer小僧の2倍の領域を持つLongの兄ちゃんやったら100
 00(Integerの5000に対して)回まわらなワリ合いまへんで、ホンマ。
           Integer  2
           Long     4
           String  10+
        Variant(数).....    

 まぁ、なんですわ、今日日パソコンも長足の進歩を遂げてメモリ不足なんぞ気ぃにせん
 でもええ時代になりましたさかい、どっちゃでもよろしいんかも知れまへんけど、他人
 のパソコンや言うて景気ようメモリを使うような指導は厳に戒めとります、うんうん。
 (コレ自分に言い聞かせてる)

 何せほら、先日やっと超がとれた初心者ですさかい、ぎょうさんある疑問の中のひとつ
 がこれでんねん。とげが刺さったように気ぃになってますさかい、大兄のご意見、ご教
 授お待ちしております、ハイ。
       (おいぼれ弥太郎)


 変数の宣言はメモリを確保することに変わりはありません。

 大きく変わったのは時代とともに、変数の型の取り扱い方が変わったのです。
 昔は変数を宣言しないと、コンパイルエラーでアウトでした(FORTRAN,COBOL,C)

 時代が変わって、VB,VBAなどVariantという便利な型が使えるようになってきて、
 黙っているとVariantになるというプログラマ無用の簡単言語が登場しました。

 このボードでも、変数を宣言していない、マクロが頻繁に登場します。
 そう、宣言しなくても動くから話がややこしいのです。

 私の答えははっきりしています、変数は必ず宣言しましょう、
 Option Explicit は必ずいれておきなさい。

 メモリの節約(いまどき?)もですが、くだらない変数名のミスで
 時間をむだにしたくないからです。
 (kazu)

 kazuさん、さっきはふてくされてもう寝る言うてましたけど、コレ見たらそう言うわけ
 にはイカンようになりましたわ、えぇ。
 早速のご教授有り難うございます。
 正直言いまして生得的に横着なこの私、ずいぶんVariantに尻ぬぐいさせてきましわ、
 ホンマに。せやけどあのバイト数見たらこらアカンなぁと実感しました。
 ま、「なんや、その程度の知識しかないんかいな」と思われるんは、それが現実です
 さかいしょうおまへんのやけど、やっぱし質問者に納得して貰わん事には(それだけ
 説得力のある)解答を出した甲斐がないっちゅうもんですわなぁ。反省、反省。
  これからも宜しくご指導の程お願い致します(おいぼれ弥太郎) 


  ★間違っているかもしれないので、ここからは真剣に読まないで下さい。
  周知のとおりVariantは、どのような型にも使えますが、その分メモリの消費量が
 多くなり、処理速度も遅くなります。小規模なプログラムであれば、問題はありませんが、
 大規模なプログラムにとっては、大きな影響があります。
 勝手に型変換が行われるため、予想外のエラー及び誤動作の原因となる恐れがあります。
 暗黙の型変換に頼ると、そのうち訳の分からないエラーで困ることになるでしょう。
 また、Option Explicit を記述しておかないと変数名を間違えても、
 Variantで宣言したと見なされるので、デバッグで苦労するだけですね。
 しかしエラーが発生すればまだ良いですが、動作するのに結果が予定と違う場合は
 最悪でしょう。
 ただし、Variantでしか対応できない状況もありますので、
 使ってはいけないと言う意味ではないので、間違えないで下さい。 
  私は最初のころ勘違いしていました。(^_^;)

 それと、Integerは16ビット、Longは32ビット、OSも32ビット。
 Integerのメモリ消費は Longの半分で一見有利ですが、レジスタに読み込んだ後、
 使われない半分を処理する必要があるので、その分遅くなるようです。
 それに比べLongであれば1回のアクセスで処理されることになります。
 その為、ループカウンター等ではLongを使った方が処理速度が高速になるようです。
   (INA)

 kazuさん、INAさんとダブるところもありますが...

 そもそも他のプログラミング言語では変数を必ず宣言しなければ使えません。
 弥太郎さんが書いているように「このメモリ領域を使って作業します。」と
 宣言するわけです。
 それは同時に「これ以外の領域は使いません。」ということにもなります。

 ところが配列などは添字をループで回しすぎて、確保したメモリ領域を超えてしまう
 こともあります。
 お隣のメモリ領域では別の目的で使用されるプログラムやデータが格納されていることもあり、
 そんなときはハングアップしたり、他の変数のデータを書き換えてしまうこともあります。
 配列とループは注意しませう。Variantは配列の形も取ります。

 話は変わって80286がDOS時代最後の16bit機みたいですね。なつかしぃ。
 DOSの時代は16ビット主流でしたからIntegerのほうが効率よかったのですよ。

 もちろんメモリは有限ですから、できるかぎり無駄のない方がいいですけど
 これはその自動化した作業の性質によると思います。
 対話型でリアルタイムな処理を必要とするなら速度を優先する必要がありますよね。
 銀行でお金をおろすのに10秒でデータ処理できる端末と、20秒かかる端末だったら、
 待つ身としては待ちが少しでも短いほうがいいわけです。
 10番目のお客がサービスを受けるのに100秒の違いがでます。
 ですからメモリを多少余分に使用しても処理速度を優先することもあるのです。
 ちなみに冗長なプログラム(コード)のほうが処理が速くなります。

 変数の宣言については、私はここではサボって宣言していない部類の人間なんで
 宣言しといたほうがいいですよぉ程度にしておきます(汗)。
 (ramrun)

 INAさんの、
 > ループカウンター等ではLongを使った方が処理速度が高速になるようです。
 について、整数を扱う部分でLongを使っても精度は大丈夫なのでしょうか?
 私は、マクロは全くの素人ですが、
   For i = 1 To 10000
   Next
 を計算するとき、iの値に誤差が付いて、結果、10001回ループが回った…などは
 原理的には発生しないのでしょうか?
 (ちゅうねん)

 誤差? それってdoubleと勘違いしてません?
 多分、doubleを使っても変化分は1なので誤差は無いと思います。

 ただ、よくある間違いは

 For i = 0 To 10000
 Next

 For i = 1 To 10000
 Next

 0からはじめるのか、1からはじめるのかです。

 (ramrun)

 お恥ずかしい。doubleと勘違いしていました。ramrunさん、ありがとう。
 (ちゅうねん)


最初の質問者の(よ)です。みなさんのお話し、正直???ですが、何とか読ませていただいております。

ところで、超初心者のわたしにもう一つ教えてください。
kazuさんやみなさんがおっしゃっている、

Option Explicit とはどういう時に使うのですか?普通に宣言するのとは違うのですが?


 普通にモジュールの先頭行に記述して構いません。
 ただ毎回記述するのが面倒なので、VBEの
 [ツール]−[オプション]−[編集]−(変数の宣言を強制する)にチェックを入れると
 自動的に記述されるようになります。
 Option Explicit が記述されていると
 Dim A のように 変数を宣言する必要があります。
 宣言しないで使用すると エラー が発生します。

 よって、以下のような場合、4行目でエラーが発生します。

  Option Explicit
  Dim ABCD As String
  ABCD = "TEST"
  MsgBox ABCE

    Option Explicitが無いと MsgBox は 空欄で表示されてしまいますので、
    自分でミスを探さなくてはなりません。 

   (INA)


 (INA)さん、ありがとうございました。今まで何度か見かけたことはあったのですが、ようやくわかりました。もっと勉強します。(よ)

 エライ遅うなってすんません
 のっぴきならぬ出来事が発生しまして、申し訳おまへん。深謝。
 美酒が未だに胃の腑に残ってもて...

 ramrunさんの銀行の例、適切且つ明快で私どもみたいな初心者にはうってつけの講義
 でしたわ、えぇ、えぇ。いちいちごもっともやと思います。
 冗長なコードの件も然りですわ。cpu100ペンティアム、メモリ16MBの時代、ロータスで
 遊びでマクロ(そんな名称やなかった)組んどった時、ForやDoで作業するよりIF文で
 書き流した方が処理速度が高くなる事を発見しましてな、わざわざIF文に書き換えた事
 を思い出しますわ。そうした観点からすれば、小生のマクロは「処理が速いッ!」っち
 ゅう事になりまんねんけど、コレはあんまり自慢せん方がええみたいでんなぁ、うん。

 Option Explicit を初めて目ぇにしたんわramrunさんのコードでしたわ、えぇ。
 で、勉強のためにコピーしとったんですけど、他のコードを廻すたんびに「変数が定義
 されとらん!」いうてイチャモン付けられましたんで、「なんやコレッ!」と
 早々に消し去りましたわ。今から思えば小生の不精者を是正する、格好の監視役を捨て
 去ったみたいなもんで大いに反省してますわ、えぇ。

 kazuさんにもお小言もらいましたし、これからはExplicitをイの一番にタテ祭ってこ
 の性根をたたき直して貰いまっさ。(ヘヘッ、信じられまっか?)

 INAさん、相変わらずあらゆることにご精通のようで、今更ながら感服つかまつります
 わ、えぇ。
 Longの宣言が、Integer ではRowsの破裂を招くっちゅうお答えが返ってくるもんやと
 私は思うとりましたんで、意外な展開につい引っ張り込まれてしまいましたわ。 
 おかげでわたしゃトゲが抜けてすっきりしましたで、えぇ。おおきに。

 なんのかの言うて、チャッカリ先達者の知恵と知識を拝借しては身ぃに纏うておりまん
 ねんけど、そのうちスッキリ着こなせるようになりまっしゃろか。と、自分の成長を過
 評価しとる今日ですわ、ハイ。
    一歩前進の(おいぼれ弥太郎)


コメント返信:

[ 一覧(最新更新順) ]


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