読者です 読者をやめる 読者になる 読者になる

t-hom’s diary

主にVBAネタを扱っているブログです。

VBAの研究・考察

VBAでアホな実験 ~ Not演算子は何個連続で使えるか

二重否定文…それは時に控えめな肯定を、時に強い肯定を生み出す日本語のテクニックである。控えめな肯定の例「できなくもない」 強い肯定の例「やらねばならない」なんてことを考えてたら、そういやNotって二個以上つなげても大丈夫なんかしらと、アホなこと…

VBA クラスモジュールでRangeの仕組みを説明する

昨日公開した以下の記事について、比喩ではちょっと難しいという声をいただいたので、今回はクラスモジュールを使って私が想像するRangeの仕組みを具体的なコードで解説しようと思う。 thom.hateblo.jpまずはSheetの模擬クラスとRangeの模擬クラスを用意する…

VBA Rangeオブジェクトはシートを操作するエージェント

VBAで扱える代表的なExcelのオブジェクトにWorkbook、Worksheet、Rangeなどがある。 ひとつのブックにはひとつのWorkbookオブジェクトが対応している。 ひとつのシートにはひとつのWorksheetオブジェクトが対応している。 ではひとつのセルに対応する固有の…

VBA プロシージャのオーバーロード機能(もどき)を自作する

今回のネタは@mmYYmmddさんのつぶやきから生まれた。感謝。さて、オーバーロードとは。 ふつう、Functionが取れる引数の数や型は固定されていてあまり自由が利かないのだが、引数の数や型によって処理を振り分けたい場合がある。 VariantやOptional、ParamAr…

VBA WSHとScriptingに存在するFileSystemObjectは同一のバイナリーであることが判明

VBエディタから参照設定で「Windows Script Host Object Model」と、「Microsoft Scripting Runtime」の両方にチェックを入れると、どちらのライブラリにもFileSystemObjectが存在する。 今回はこの2つが同じものなのか、それとも別物なのかを検証してみた。…

VBA マクロ、プロシージャ、メソッドなどの用語について正確に理解する

初心者向けの解説によくマクロとVBAの違いが取り上げられる。 一応違いについて説明した後、同じようなものなのであまり気にしなくて良いと締めくくるケースも多いけど、私はやはり違いを意識したほうが良いと考える。初心者は同じようなものと言ってくれた…

VBA デザインしたユーザーフォームを元にNewで複数のフォームインスタンスを作る。

VBAでユーザーフォームはふつう、単一のオブジェクトとして扱う。たとえば以下のようなフォームを作ったとしよう。 オブジェクト名は「frm成績」としたので、このフォームを表示させるコードはこうだ。 Sub hoge() frm成績.Show End Sub この時フォームは、…

VBA MsgBoxのオプションはなぜ足し算できるのか

VBAのメッセージボックスでは、以下のように適用したいスタイルを足し算できる。 Sub hoge() MsgBox "処理を続行しますか。", vbYesNo + vbQuestion + vbDefaultButton2, "確認" End Sub 上記のマクロを実行すると、このように表示される。 変な文法だと思わ…

VBA 複数の引数をとるPropertyプロシージャ

これまでProperty Getは複数の引数を受け取ることができないと思っていたが、昨日Twitterで以下のご指摘をいただいた。@thom__jp https://t.co/pgPwIa8S2pの記事で少し気になったのですが、PropertyLetは複数の引数をとれる(最後の一つが右辺、残りは左辺の…

VBA PowerPointでShapeを一気に削除するマクロ

こちらのブログで、PowerPoint VBAでFor Eachを使ってShapeを消すとうまくいかないという問題が紹介されていた。chemiphys.hateblo.jpやってみたところ、実際に1つ飛ばしで削除される。 実際に検証 Excelで検証してみた。 Sub Excel版ShapeAdd() Dim i As Lo…

VBA プロシージャ呼び出しのオーバーヘッドについて

今回はVBAでプロシージャ呼び出しにかかるオーバーヘッド時間を計測してみた。 プロシージャ呼び出しのオーバーヘッド改善はコンパイラの領分 一般的に、プログラミングではプロシージャの呼び出しにはオーバーヘッドが発生すると信じている方もいるようだけ…

VBAの標準モジュールはオブジェクトなのか

結論として、私は最近標準モジュールを「オブジェクト」と見做すようになったのだが、そのあたりの経緯と悩みをうだうだと書こうかと。 MSの公式見解によると、標準モジュールはオブジェクト モジュールではない Excel VBAでコードを書ける場所は、Microsoft…

VBA インターフェースとは、プロパティやメソッドの存在を保証する規格のようなもの

プログラミングの学習途中で、いくつか難しい概念にぶつかる。 インターフェースもその一つだと思う。このインターフェースは、フォームのボタンなどの、ユーザーインターフェースのことではない。 クラスモジュールなどで作ったオブジェクトに適用するイン…

VBA Propertyはフィールドのフリをしたメソッド ~ プロパティに値を代入するという表現は厳密には正しくない

プロパティーに値を代入するという表現をよく見かける。 私もつい最近までそのように表現していたけれど、これって厳密には間違ってるんじゃないかと思い始めている。 というのも、Propertyプロシージャを学習する際、この「代入」という表現が理解を難しく…

VBA クラスモジュールで連結リストを作成する方法

今回はクラスモジュールを使って連結リストを作成してみる。 実験ではなく、必要性があって作ることになったのでそういう意味では実用的なサンプルとして紹介できるかと思う。 連結リストとは 情報処理技術者試験などで学習したことがある人も要ると思うが、…

VBA 自作クラスのBeforeChangeイベントでCancel処理をする方法

さて、前回は自作クラスにEventを実装する方法について説明した。 thom.hateblo.jp前回紹介したマクロはMoveNextをクリックするたびにカーソルが下に移動するというものだったが、CursorオブジェクトのValueに上限・下限を設けていないためクリックし続ける…

VBA クラスモジュールに自作のEventを実装する

今回はクラスモジュールに、自作のEventを実装し、シートモジュールでクラスのイベントを受け取る処理をやってみる。 まずはEventを使用しないクラスサンプル クラスモジュールを挿入し、以下のコードを貼り付け。 ※サンプルなのでクラスモジュールのオブジ…

VBA オブジェクトとメモリの関係 ~ オブジェクトが参照型と呼ばれる理由

前回、VBAを擬人化して、変数が記号表によって管理されているというところまで書いた。※読んでない方はこちら thom.hateblo.jpさて、今回はオブジェクトがメモリ上でどう扱われるのかという話。次のコードで説明しようと思う。 Dim c As Collection Set c = …

VBA 変数とメモリの関係 ~ 値渡しと参照渡しをメモリの動きから理解する

今回は変数とメモリの関係について書こうと思う。 ちょっと「記号表」とかいろいろ難しいモノが登場するのだが、ちょっとわかりやすく説明するためにVBAを擬人化しておこうと思う。 コンパイラー君とインタープリターさんの紹介 まずあなたがVBAコードを書く…

VBA シートと不可分のマクロはシートモジュールに書くとスッキリする

VBAの書籍を見ていると、だいたい標準モジュールにマクロを書くように指示されている。マクロの記録で保存されるのが標準モジュールということもその理由かもしれないし、そもそも「標準」という名前が「ふつうはここに書け」という指示に見えるのかもしれな…

VBAの特徴について ~歴史、利用者層、サポートするパラダイムと型付けの作法など

これまでVBAについて色々記事を書いてきたけれど、VBAってそもそもどんな言語なのか、自分が学んできたことを整理する意味でひととおり書いておこうと思う。 VBAの歴史をざっくりと説明 VBAの祖先はアメリカのダートマス大学で作られたBASICという教育用言語…

VBA モデル化の概念を理解すると、クラスモジュールの使い方が分かる

クラスモジュールを使いこなすためには、モデル化という概念をおさえておくと分かりやすい。しかしいきなりモデル化といわれても何のことかわからないと思うので、順を追って説明していく。まずプログラミングにおけるモデル化の話をする前に、モデルという…

VBA オブジェクト変数の宣言時にNewすると何がまずいのか

オブジェクト変数の宣言と使用については、以下の2パターンが存在する。■パターン1 宣言と同時にNewしてしまう方法 Dim C As New Collection■パターン2 宣言とオブジェクトのSetを分ける方法 Dim C As Collection Set C = New Collection私はこれまで大体の…

VBA 配列とコレクションの違いをメモリ上のデータ構造から理解する

VBAでは複数データを格納できるデータ型として、配列とコレクションがある。 それぞれ一長一短あり、どちらが優れているというものではないのだが、どちらかといえばデータの追加・削除が簡単に行えるコレクションのほうが使い勝手は良いかもしれない。さて…

VBA なぜ引数が一つのときは、カッコを付けても付けなくてもプロシージャを呼び出せるのか

初心者の方はプロシージャ呼び出しの時にカッコを付けるかどうか迷う方もいると思う。基本ルールは、Callを書く場合と、戻り値を利用する場合にカッコを付け、それ以外では付けてはいけないである。以下のように、不要なカッコを付けると、コンパイラに叱ら…

VBA Cellsの正体は、全セルを包むRangeオブジェクトである

セルを行・列の数値で指定するCellsはRangeと並んで基礎中の基礎であるが、その正体を知る者は少ない。まあ別に知ったところで使い方が変わるわけではないのだが、知っておいて損になるものではないので紹介しよう。今回も評価という用語を用いるので、意味…

VBA Sheetsの後にドットを入れても入力候補の自動補完がされない理由

'============▼2016/5/31追記▼============Workbooksオブジェクトは存在しないと書きましたが、Microsoft MVPの伊藤さんから誤りを指摘いただいたので修正しました。伊藤さん、ありがとうございます。【参考】 SheetとSheetsとWorksheetとWorksheets:エクセ…

VBA 参照設定とCreateObjectは全く別の経路でオブジェクトを参照する。

昨日以下の記事を書いた。 thom.hateblo.jp要約すると、レジストリのHKEY_CLASSES_ROOT直下にプログラムID(InternetExplorer.Application等)のキーがあり、その下のCLSIDにGUIDが入っているのでそれをまたレジストリから辿ると、TypeLibを辿れるというもの。…

VBA ReDimはなぜ最後の次元だけしか拡張できないのか。

多次元の動的配列を作ることがある。コードはこういう感じだ。 Dim Arr() As Byte ReDim Arr(1 To 3, 1 To 3) 最初のReDimは拡張というよりは初期化なので、これはうまくいく。3×3のサイズの配列なので、イメージとしてはこんな感じだろうか。 ところでこの…

VBA Set Obj = Nothing は必要か

オブジェクト変数を使い終わった後、必ず変数にNothingをセットしているコードが多いが、実はあれは別に無くても良い。Nothingを代入することでオブジェクトが破棄されると思っている方も多いと思うが、厳密には違う。オブジェクトの破棄のタイミングは、オ…

VBA 巨大な表を配列に入れるとメモリはどうなるのかという心配について

以前このブログでも紹介したが、セル範囲と2次元配列は相互に変換できる。thom.hateblo.jpたとえばこんな風に。 Sub セルから配列へ() Dim Arr() As Variant Arr = Range("A1:Z100") End Sub Sub 配列からセルへ() Dim Arr(1 To 100, 1 To 26) As Variant Ra…

VBA Newキーワードの使い方は2種類だけではない。 ~ With New Objectという使い方。

オブジェクトを扱うときに登場するNewキーワード。おそらく以下の2種類の使い方が一般的かと思う。まずは、変数へ新規インスタンスをセットする際に使うNew。 (以下のObjectには任意のオブジェクトが入る。例:Collection) Dim obj As Object Set obj = New O…

VBA ジョージ・ブールとIf文とBoolean

VBAのBoolean型は、由来をたどれば数学者ジョージ・ブールの名前である。 ある意味、この方のおかけで今のIf文があるといっても過言ではない。Googleのトップページで知ったのだが、今日はブールさんの生誕200周年らしい。おめでとうございます。以下Wikiped…

VBA 改行コードにまつわる話 ~vbCrLfとは

VBAで文字列を改行する方法はいくつかあるが、ネットのサンプルなどで一番多いのはvbCrLfだろう。Wikipediaによると、CrLfとはタイプライター時代の用語(キャリッジリターン・ラインフィード)の略らしい。 タイプライターはタイプするたびに印字装置が左か…

VBA コードの抽象度とは

具体的、抽象的という言葉について 一般的には、「具体的でわかりやすい」とか、「抽象的でわかりにくい」という使い方をする。具体的でわかりづらい、抽象的でわかりやすいと言われても、「は?」と思う方が大半だろう。ただプログラミングのような緻密な作…

VBA LetとSetとCallとカッコ

過去記事で、すべての行はステートメントであり、省略せずに書くとLetやCallが付くことを説明した。thom.hateblo.jpLetについてはプロパティプロシージャでの使用が大半で、代入にわざわざ書いている人はあまり見たことが無い。 Subプロシージャ呼び出しの場…

VBAの本体はどこにあるのか

今回も雑学ネタ。特に役立つ話ではない。以前からVBAの正体が気になって仕方がなかったが、昨日ようやくその正体を突き止めたので書き留めておく。まず、VBエディタのツールから参照設定をすると、そこにVBAがいる。 VBAへの参照設定はどうやっても外すこと…

VBA 0.1 + 0.2 = 0.3にならない。

この記事の元ネタはVB.NETやC#に関してのもの。 「どぼん!」さんのサイト「DOBON.NET プログラミング道」で見つけた。 小数(浮動小数点数型)の計算が思った結果にならない理由と解決法、Decimal型はいつ使うか?: .NET Tips: C#, VB.NET最初、「えっ?こ…

VBA 指数表記と誤差

【注意】この記事は推測を含み、事実とは異なる可能性があります。とあるブログ(既に閉鎖)で、Exp関数に1を与えてi乗してLogを取ると、iが8と16のときに不一致になるとの報告があった。 数学的には、一致するはずである。これは面白い発見だ。実際に検証して…

VBA 関数呼び出しの際、Variant型の仮引数に別型の実引数を参照渡しするとメモリアドレスが変わってしまう事象

以下の記事で、ByRef x As VariantにLongやStringなどの別の型を渡すとメモリアドレスが変わるとの紹介が。 mmyymmdd.hatenablog.com前回私が書いた記事もそこがネックだった。 thom.hateblo.jpさて、この事象について、色々試していたら原因が見えてきたの…

VBA IntegerはLongよりパフォーマンスが悪い

ついさっき知った事であるが、VBAにおいては、Integer型を使うパフォーマンス上のメリットは皆無のようだ以下、MSDN 整数型、長整数型、およびバイト型 最近の VBA のバージョンでは、データ型が整数型と指定されている場合であっても、すべての整数値が長整…

VBAでは少数を完璧に計算することが出来ない ~ アドホックな回避策と正しい回避策

「VBAでは」と書いたが、これはどの言語にも言える話。発端は以下のツイート。子供たちには伸び伸び育ってほしいが、1から0.001を千回引いても0にならないからといって適当なアドホック実装入れて無理やり0にするような大人にだけはなってほしくない。— 加藤…

VBA なぜParamArrayは参照渡しできないのか

今回はタイトルの問いに対し、根本回答が見つかっていない。 一応、分かる範囲で検証してみたのでその結果報告である。 背景 mmYYmmddさんがメモリ効率に関して記事を書いてくれたので確認。 qiita.comなるほど、C++を経由してポインタでSwapする手があった…

VBA Now関数は実はFunctionではなくPropertyとして定義されている その2

先ほど以下の記事を投稿したばかりであるが、ひとつ勘違いが判明したので訂正記事。 thom.hateblo.jp Now()はDateTimeクラスのプロパティと書いたが、そもそもDateTimeはクラスではなくてただのモジュールだったようだ。「オブジェクトブラウザ」は、その名…

VBA Now関数は実はFunctionではなくPropertyとして定義されている

VBAのNowは、結論から言えば、MSDNに関数と表記があるので、関数と呼んで良いのだろう。文字列と日付の操作:VBAのヒントとコツ VBA では、現在の日付や時刻を正確に調べるための関数として Now、Date、Time の 3 つの関数が提供されています。Now 関数は、D…

Excel VBAのRangeは、実はVBAの命令ではない

今回は雑学的な話。 しかも間違ってるかもしれないので、鵜呑みにせずあくまで一つの仮説として読んで欲しい。私が超初心者のころは、よくある勘違いとして、マクロの記録機能をマクロだと思っていた。でも今回はそんな勘違いの話ではない。一般的なマクロと…

当ブログは、amazon.co.jpを宣伝しリンクすることによってサイトが紹介料を獲得できる手段を提供することを目的に設定されたアフィリエイト宣伝プログラムである、 Amazonアソシエイト・プログラムの参加者です。