● Access2000VBA・Excel2000VBA独学~ExcelVBAの学習方法~「急がば回れなExcelVBAの基礎」・目次とサマリーもどき
※まだ書きかけです。すみません。
※間違ってたらすみません。
※メモ書きなので、自分でも意味不明な箇所も多いです。ごめんなさい。
目次
【目次内補足】
・重要図たち(一語一句、一単語でも意味が分からないものがあったらいけない図たち)
でないと効率化なんて夢のまた夢だから。
↓ 上の幾つかの図を集めて作ったExcelVBAの基礎のマインドマップ的な相関図メモの例。『●VBAの基礎の相関一覧図.xlsx』のZIPファイル→こちら (ダウンロードして解凍後、ファイルオープンしてから ↓ この図が表示されるまでが少し時間がかかるかもです。)
↑ この図をクリックすると、PDFが開きますが、すべての横書きテキストボックスで、文章のおわりが途切れてしまっています。また、拡大すると画像が荒すぎてまともに見えません。なので「大体わかればいい」というときなどにお使いください。
「Ctrl+マウスホイール回転」、で拡大すると、文字だけはきれいに見えます。
正式には(正常表示できるものとしては)、前述の、xlsxファイルのほうが見やすいので、そちらもダウンロードして見てみてください。
テキストボックス内の文の途切れもありませんし、図中の「変数に関する表」をもう少し詳しくしたシート「●変数と生データに関する一覧表_詳細」が2枚目に付いています。
基本、この図の「一語一句でも」、わからないところがあったら、絶対に中級には上がれません。自力でのエラー解決も難しいので それまでVBAの学習にかけた時間やお金もドブに捨てる可能性が大です。私はExcel自体のド素人なので図が間違っているかもしれませんが、そうでしたら、先生や先輩に、「わかるまで何百回でも」何がどう間違っているかを聞いてください。もちろん普通にわからないところも。
・黒文字の説明部分も含め、一語一句、一単語でも意味が分からないものがあったらいけない補足
でないと効率化なんて夢のまた夢だから。
★「モジュール(= ”プログラム=プロシージャ” を書くための白い紙)」の種類
・クラスオブジェクトモジュール(シートモジュール、ブックモジュール、ユーザーフォームモジュール)
※シート、ブック、ユーザーフォーム、の、ある特定のそれらと1対1で紐ついたモジュールです。
・標準モジュール
※特定のシート、ブック、ユーザーフォームとは結び付いていない、かつ、
「色んな場所から自由に呼び出せるプロシージャ」が書けるモジュールです。
※ただし、「開発」タブの「マクロの記録」メニューでマクロを作ると、これが自動生成(自動挿入)され、
そしてその中に 記録したマクロのSubプロシージャ(VBAコード)も自動生成されます。
ココに 手作業でSubプロシージャを作ると、「開発」タブの「マクロ」メニューの中にその名前が載ります。
「マクロの記録」で自動生成されたSubプロシージャ、手作業でココ標準モジュールに作ったSubプロシージャ、
共に、「マクロ」メニュー、クイックアクセスツールバー、リボン、その他ツールバーなどから呼び出せます。
・クラスモジュール
※「オブジェクト」と呼ばれるユニット(≒ロボット)を自作するためのモジュールです。
※自作の「プロパティ」「メソッド」「イベント」なども作れます。
★「モジュール」の中に書き込む「プロシージャ」の種類(プロシージャ=プログラムの最小単位)
・イベントプロシージャ(Subプロシージャの仲間。)
※「オブジェクト」が保持・内包する「イベント」という機能によって「自動実行される」プロシージャのことです。
※前述の「クラスオブジェクトモジュール」に書いたコレは、「マクロ」メニューからは呼び出せません。
※原則、同一の「クラスオブジェクトモジュール」内のプロシージャからしか呼び出せません。
が、少し細工をすることで、他の「クラスオブジェクトモジュール」や「標準モジュール」のSubプロシージャ、
Functionプロシージャからも呼び出すことができます。
・Subプロシージャ(標準モジュールに書いたコレ、だけが「マクロ」メニューから呼び出せます。)
※「マクロの記録」ではコレが自動的に標準モジュールに生成されます。※標準モジュール挿入も自動です。
※そのため、SubプロシージャはExcelやAccess、Wordの中では「ある意味 ”メインプログラム” 的な存在」です。
※標準モジュールやクラスオブジェクトモジュール、クラスモジュール、つまり、「すべてのモジュール」
に書くことができます。(一部、「細工なしで呼び出せるか呼び出せないか」の違いはありますが。)
※他のSubプロシージャやイベントプロシージャ、Functionプロシージャから呼び出して実行できます。
・一般データを返すFunctionプロシージャ(ワークシートのセルの数式から呼び出せるものも作れます)
※一般的には、「値を返すFunctionプロシージャ」と呼ばれます。
ここでは「オブジェクトを返すFunctionプロシージャ」と区別をするために、あえて
「一般データを返す」と表現しています。
「一般データ」とは、「リテラル値」「文字ベースのデータ」「文字系データ」のことです。
(文字列、数値、日付、True/Falseなどの2値、などのことです。「オブジェクト」とは違います。)
※Subプロシージャやイベントプロシージャ、他のFunctionプロシージャから呼び出して実行できます。
※標準モジュールやクラスオブジェクトモジュール、クラスモジュール、つまり、「すべてのモジュール」
に書くことができます。(一部、「細工なしで呼び出せるか呼び出せないか」の違いはありますが。)
※この理屈を学ぶと、ヘルプや、特に「オブジェクトブラウザ」が理解しやすくなります。
・オブジェクトを返すFunctionプロシージャ(値ではなくオブジェクトを返します。)
※これも、「すべてのモジュール」に書くことができます。
(一部、「細工なしで呼び出せるか呼び出せないか」の違いはありますが。)
※Subプロシージャやイベントプロシージャ、他のFunctionプロシージャから呼び出して実行できます。
※この理屈を学ぶと、さらに、さらに、ヘルプや、特に「オブジェクトブラウザ」が理解しやすくなります。
・値を返さない・何らかの処理をするためだけのFunctionプロシージャ
※これも、「すべてのモジュール」に書くことができます。
(一部、「細工なしで呼び出せるか呼び出せないか」の違いはありますが。)
※Subプロシージャやイベントプロシージャ、他のFunctionプロシージャから呼び出して実行できます。
・Propertyプロシージャ(自作オブジェクトの「プロパティ」を自作するためのプロシージャです。)
★「プロシージャ」の中に書き込む要素(プロシージャを構成する要素)
・生データ=「リテラル値」や「オブジェクト式」のこと=「変数」に代入されるもの・・・、です。
※リテラル値=文字ベースのデータのことです。文字列、数値、日付、True/Falseの2値などの生データ。
「変数とは違う値」「変数には代入されていない値」という感じで、「変数」の対義語としても使われます。
当サイトでは「一般データ」「文字系データ」とも呼んでいます。
※リテラル(literal)の直訳=文字どおりの、誇張なしの、(文字どおりに)まったくの、いわゆる「まんま」。
https://wa3.i-3-i.info/word15346.html もご参考に。
※オブジェクト式=「オブジェクト」と呼ばれるユニット(≒ロボット)を単語化し、式にしたものです。
ある意味「オブジェクト」としての生データです。
(言ってみれば、「オブジェクト」の「リテラル」という感じです。)
・変数(一般変数、オブジェクト変数)
※「プログラミング」とは、どんな言語であっても「変数」を自由自在に動かして「自動化」を実現する作業のこと。
※「変数」という仕組みがあるから、プログラムが「汎用化」できます。
「マクロの記録」で作ったマクロにはコレや、後述する「関数、ステートメント」等々が抜け落ちているので
汎用化されていません。特定の場面でしか使えません。(でもそれでも役に立ちますが。後述。)
※「変数」は「クリップボード」に似ています。文字系データも図形(オブジェクト)も一時保管ができます。
名前付きのクリップボード・・・というイメージと似ています。
※一般変数=リテラル値を代入するための変数です。
※オブジェクト変数=オブジェクト式を代入するための変数です。
・配列(「一括処理」がしやすくなって変数のことです)
・定数(消費税率など、プログラムの中で「不変」にしたい値を格納する「変数の仲間」です)
・列挙型変数(ある意味定数の仲間。)
※「色」など、よく使う共通のものを定数化し、インテリセンス(自動補完ドロップダウン)で扱えるようにします。
・演算子(計算=四則演算、比較、データ抽出、その他)
・VBA関数(主に一般データを加工したり動かしたりしてくれる命令語句です)
※基本的に、一般データ(文字系のデータ=文字列・数値・日付・2値、など)に使うことが多いです。
※多少、オブジェクトに対しても使えるものもあります。
※俗にいう「Excel関数(=ワークシート関数)」とは異なります。
※ただし、VBAで使えるワークシート関数もあります。(「WorksheetFunction」にてほとんどが使えます。)
・ステートメント(繰り返し文=ループ文、条件分岐文、エラー処理文、など、)
※一般変数(生一般データ)、オブジェクト変数(生オブジェクト)、の両方に共通の命令語句です。
・オブジェクト(生オブジェクト=オブジェクト式、部分オブジェクト式)
と、オブジェクトが保持・内包する5つの機能
(プロパティ、メソッド、イベント、ユーザー入力値、階層構造上下自由往来機能)
・列挙(=列挙型=列挙体=Enum)、組み込み定数
・ADO 、または、DAO(=ミドルウェア。閉じたExcelファイルの読込、「書き換え」、その他色々に使う機能です。)
・SQLとSQLの集計関数(データ管理・データ操作の「世界標準」の命令語句 or 機能 or 理論 =「複式簿記」と同じくらい有名です。Accessとの連携がしたい場合は必須です。)
★上記の要素のうち、「生一般データ・一般変数」を動かす(=操作・加工・計算等々をする)ために使う要素
・リテラル値=生データ=一般データとしての生データ(文字列、数値、日付、True/Falseなどの2値)
・一般変数(文字列型、数値型、日付型、Boolean型、など、リテラル値=一般データの生データを代入したモノ)
・配列
・定数
・列挙型変数
・演算子(計算=四則演算、比較、データ抽出、その他)
・関数(多くつかう。オブジェクトに対して使うことは少ない。)
・ステートメント
・「ADO、DAO」で、閉じたファイルに接続した後に、そこから取得した文字系の一般データの値の加工のみ
・SQLとSQLの集計関数
(ADO、DAOなどで閉じたファイルに接続した後に、そのファイルのデータの読み書きの命令文字列。)
★上記の要素のうち、「生オブジェクト・オブジェクト変数」を動かす(=操作する)ために使う要素
・オブジェクト式=生データ=「オブジェクト」としての生データ(=オブジェクト式)
・オブジェクト変数
(Range型、Workbook型、Worksheet型、Object型など、オブジェクトの生データ=オブジェクト式を代入したモノ)
・演算子(比較、データ抽出、その他)
・関数(ほんの少し)
・ステートメント
・オブジェクトが保持・内包する5つの機能
(プロパティ、メソッド、イベント、ユーザー入力値、階層構造上下自由往来機能)
※特に、「文字系データの操作」の「関数」のかわりになるものが「メソッド」です。
「メソッド」は特定のオブジェクトに紐ついた命令語句です。「関数」と関係が深いです。
「開く」「閉じる」「印刷する」「コピー」「貼り付け」「削除」「検索」などの、
画面上に「メニュー」として存在する命令もあれば、メニューには存在しない命令もあります。
・列挙(=列挙型=列挙体=Enum)、組み込み定数(色やセル書式の設定などの、各種設定項目や設定値です)
・「ADO、DAO」の中に含まれる「オブジェクト」
※閉じたExcelファイル、テキストファイル、SQL Server、MySQLなどへの接続や行/列操作などで使います。
Connctionオブジェクト、レコードオブジェクトセット、などをよく使います。
データの読み書きにも使いますが、値そのものの加工だけは「一般変数の操作」の側で関数などを
用いて行います。
★「生一般データ・一般変数(文字系のデータ)を動かす場合」と、「生オブジェクト・オブジェクト変数を動かす場合」のウェイトバランス
1つのプロシージャのなかで「生一般データ・一般変数(文字系のデータ)を動かす場合」と、「生オブジェクト・オブジェクト変数を動かす場合」のどちらが多いかということですが、半々くらいになることが多いのではないかと思います。
もちろん、どちらかがとても多くなることもあります。
100%「生一般データ・一般変数(文字系のデータ)のデータしか動かさない」という場合やその逆もあるにはありますが、その場合は「100%文字系のデータしか動かさない」ということのほうが多いは多いです。(値の変換、加工、追加計算処理、などで)
★前述の要素のうち、「マクロの記録」メニューで作った「マクロ」の中に自動で書き込まれる要素
・オブジェクト(生オブジェクト=オブジェクト式、部分オブジェクト式)
と、オブジェクトが保持・内包する5つの機能のうちの3つ?
(プロパティ、メソッド、ユーザー入力値(?)、)
・列挙(=列挙型=列挙体=Enum)、組み込み定数
以下、本当の目次
★ はじめに
(A)本記事の目的
▼「中級」とは?
(B)なぜ「中級」に自力であがることにこだわるのか?(その目的にした理由)
(C)VBAプログラミングの中級にあがるために必要なこと(重要度順)
(01-1)プログラミングとは?VBAとは?(A図)
(02-1)「プログラムの最小単位(=プロシージャ)」についての簡単な説明
(03-0)プロシージャを書く場所の表示方法
(03-1)「プログラムの最小単位(=プロシージャ)」を「書く場所=モジュール」、についての簡単な説明
(03-2-1)プロシージャを書く場所01~クラスオブジェクトモジュール(シート、ブック、フォーム)
(03-2-2)プロシージャを書く場所02~標準モジュール
(03-2-3)プロシージャを書く場所03~クラスモジュール
(03-3)「Propertyプロシージャを使う」「クラスモジュールを使う」の意味
(03-4)「表の操作」に関してだけは「クラスモジュール」はそれほど必要ないと思います。多分。
(03-4-2)★★★★★ 必読!! ビジネス関連プログラムでの最大の要注意事項!!! Excelが間違う小数計算について(パソコンのバカさ加減について)とVariant型変数の多用の落とし穴について
(03-4-3)★★★★★★ 必読!! 要注意事項!!! オブジェクト式の「省略」が生むトラブルなどについて
(03-5)「★★★ 人間様がサボるために超重要!!よりラクになるために・よりコスパをよくするために超重要!!!」~SubプロシージャやFunctionプロシージャの呼び出しについて
(04-1)実際の『「プログラムの最小単位=プロシージャ(=小さくて簡単なプログラム)」の書き方の流れ』の事例(もっとも簡単なプログラム x+y など。)
(05-1)プログラミングの操作対象:★★★「プログラムの汎用化=効率化」に大貢献する「変数」に対する簡単な理解01(「代入」とは?「=(イコール」の意味について)
(06-1)プログラミングの操作対象:★★★「プログラムの汎用化=効率化」に大貢献する「変数」に対する簡単な理解02(一般変数とオブジェクト変数の区分やそれぞれの役割、さらに細かい種類、など)
(07-1)プログラミングの操作対象:★★★「プログラムの汎用化=効率化」に大貢献する「配列」について
(08-1)プログラミングの操作対象:「定数」についてと、VBA定数(?列挙体?)のイメージについて
(08-2)プログラミングの操作対象:「列挙型変数」について
(09-1)変数を動かす道具たち:「予約語」とユーザーが付けられる名前について
(10-1)変数を動かす道具たち:VBA関数について(数値・文字・日付などの文字ベースの各種の値の操作、ファイル操作、オブジェクト操作、など)
(12-1)変数を動かす道具たち:「演算子」について
(13-1)「★★人間様がさぼるための強い味方!!★」ステートメント01~変数宣言や代入の文
(14-1)「★★人間様がさぼるための強い味方!!★」ステートメント02~分岐処理の文
(15-1)「★★人間様がさぼるための強い味方!!★」ステートメント03~★★★★★ 繰り返し処理の文
(16-1)「★★人間様がさぼるための強い味方!!★」ステートメント04~エラー対策の文
(17-1)「★★人間様がさぼるための強い味方!!★」ステートメント05~その他の文(Withとか)
(18-1)「関数」と「ステートメント」は一般変数やオブジェクト変数の外側に居て、外側からそれらを動かすイメージ。「プロパティ」「メソッド」「イベント」はオブジェクト変数の内側に居て、内側からそれらを動かすイメージです。
(19-1)「VBE(VisualBasic Editor)」の画面の簡単な説明
(20-1)シートのイベントプロシージャの簡単な作成事例とVBEについて
(20-2)シートのイベントプロシージャ、特に「Change」イベントで起こるイベントの無限連鎖
(21-1)ユーザーフォームの簡単な作成事例とVBEについて
(22-1)「コントロール」について(オブジェクトとの違い、など)
(23-1)ユーザーフォーム上のコントロールのイベントプロシージャの簡単な作成事例とVBEについて
(24-1)「標準モジュール」の使い方
(25-1)「ワークシート関数」と「VBA関数」について
(26-1)「値を返す関数」とその自作について(オブジェクトブラウザの操作の理解に必須)
(27-1)「オブジェクトを返す関数」とその自作について(オブジェクトブラウザ操作の理解に必須)
(28-1)「マクロ」と「VBA」との違いについて
(29-1)プロシージャの種類とVBEとの関係
(30-1)モジュールとVBEとの関係
(30-2)SubプロシージャやFunctionプロシージャの呼び出しについて
(31-1)プログラミングの操作対象:「オブジェクト」の事例(実際の画面の各パーツやメニューとの関係)
(32-1)プログラミングの操作対象:「コントロール」について(ユーザーフォーム上とシート上)
(33-1)プログラミングの操作対象:「コレクション(=コレクションオブジェクト)」について
(34-1)プログラミングの操作対象:「Enum・列挙型・列挙体・列挙」と「定数」について
(35-1)プログラミングの操作対象:オブジェクトモデルの階層構造の理解(コレクション→単一オブジェクト→プロパティ、メソッド、イベント、ユーザー入力値、階層構造)
(36-1)プログラミングの操作対象:「オブジェクトの取得」の意味
(37-1)プログラミングの操作対象:「オブジェクトへの参照」の意味
(38-1)プログラミングの操作対象:「オブジェクトへの参照」の意味
(39-1)プログラミングの操作対象:すべてのオブジェクトはその1つひとつが「5つの機能」を保持している。(プロパティ・メソッド・イベント・ユーザー入力値・階層構造、は、厳密な説明を理解するより、どれも、全部、”オブジェクトが保持する「機能」たち”、と大雑把にとらえるほうが色々と理解しやすい)
(40-1)プログラミングの操作対象:「オブジェクトの取得」と「オブジェクト式」「部分オブジェクト式」について
(41-1)プログラミングの操作対象:「オブジェクトの取得」=「オブジェクト式の作成」=「オブジェクト式を書く作業」は、主に、番号でやるか、名前でやるか、列挙型の定数でやるか、の3パターンが多い。
(42-1)プログラミングの操作対象:オブジェクト変数と「真に代入されるのは”参照”」の意味についてと、でも「代入された=5つの機能が使える」と理解するほうが面倒くさくない、ということについて
(43-1)「5つの機能」はオブジェクトの内部に居座りつつ、オブジェクトを動かせる。
(44-1)「関数」や「ステートメント」はオブジェクトの外側からオブジェクトを動かせる。
(45-1)プログラミングの操作対象:「オブジェクト変数」について
(46-1)プログラミングの操作対象:「オブジェクト式」と、オブジェクト式を代入したオブジェクト変数」の関係について(イコール関係・その他の視点について)
(46-2)プログラミングの操作対象:「オブジェクト式」と、「部分オブジェクト式」について
(47-1)プログラミングの操作対象:「一般的な”コンテナ”の意味」、「ヘルプに書かれた”オブジェクト”としてのコンテナ(埋込オブジェクト:ガワ、の意味」について
(48-1)プログラミングの操作対象:ワークシートに埋め込まれたグラフの扱いとコンテナとVBEについて
(49-1)「セルの取得」「セル範囲の指定」「セルの選択」などについて
(50-1)Rangeオブジェクト(セルの取得・選択)とヘルプの重要なことについて
(50-2)RageプロパティとCellsプロパティの違いと「For Each ~Next 文」について(絶対/相対)
(51-1)「For Each ~Next 文」について
(52-1)ループ処理の構文を使わずに、セル=Rangeオブジェクトの一括処理(並べ替え・検索・データの書き換え、その他)ができるメソッドやプロパティ等々
【一括選択】
【並べ替え】
【検索】
【DAOやADOのレコードセット丸ごとの一括シート貼り付け】
【DAOやADO、Microsoft Queryで、ループ処理を使わずに、SQLで一括データ書き換え】
【表のデータ(セル範囲)を一括でコピー、別のシートにペースト】
【フィルタをかけた表の結果(セル範囲)を一括でコピーまたは削除】
【Variant型の変数に、「配列として」表のデータを一括で代入し、別のシートに一括転記】
【Variant型の変数に、「配列として」表のデータを一括で代入し、ループの高速化テスト】
(52-2)セルの最終行の取得とOffset
(53-1)単一セルごとの一括処理には基本、「For Each ~ Next文」や一括処理専用のメソッドなどを使い、カウンタ変数を用いたループ処理は特殊な場合のみ使う、ということのほうが良いかも?
(54-1)NameプロパティとCodeNameプロパティの違い
(54-2)「名前付き引数」の利用
(55-1)目的のオブジェクトのインデックス番号がわからないときのあたりの付け方
(56-1)★ ヒント:「部分オブジェクトの取得」の基本は、まずは3パターンくらいから。
(58-1)「オブジェクトブラウザ」の使い方
(59-2)「マクロの自動記録」でオブジェクト式の書き方について学ぶ
(59-3)ヘルプでオブジェクト式、部分オブジェクト式の書き方について学ぶ
(64-2)Range.CopyFromRecordsetメソッドで、DAOやADOレコードセット(表データ)をループを使用せずにExcelシートに一括貼り付け
(65-1)「For Each ~ Next文」で、DAOやADOレコードセット(表データ)の列や行を一括処理
(65-2)DAOやADOで表をレコードセット化(ある意味にオブジェクト化)することは、クラスモジュールを使って表をオブジェクト化するよりも、30~100倍は便利で効率がいい。
(65-2)DAOやADOはExcelだけでなく、Word、Access、PowePoint、Outlookなどでも使えるし、Web系のプログラム(PHPやASPなど)でも使えます。
(a)オブジェクトモデルの階層構図の全体図(オブジェクト所得・操作の羅針盤。最重要なツール。)
※Shift+TABキー、もしくは、Homeキー、Homeキー+TAB数回、を押すと、目次付近に戻れます。
お金だけあげるODAじゃなくて、現地の人が自力で解決できる力を与えるODA
初心者が「自力で解決できるようになるための」ExcelVBAの基礎
本記事に書いてあることはExcelVBA基本中の基本であり、この記事に書かれたことが分からないなら、VBAは100%初級どまりで中級以上には上がれないです。
そしてVBAプログラミングは、「中級」にあがれないなら、「コスパアップ」は不可能です。(というくらいに思っておいたほうがいいです。達人だと初級のテクニックでもコスパアップしてしまいますけど・・・。)
VBAプログラミングは、「初級のまま」では、『製作時間と「無償作成」の裏に隠された本当にかかったコスト』のことを考えると、「コスパアップ」は不可能です。(というくらいに思っておいたほうがいいです。同じく、達人だと初級のテクニックでもコスパアップしてしまいますけど・・・。)
そして本記事に書かれていることは「このなかの特にどれが重要」という話ではありませんで、「全部重要」で、「全部一語一句意味不明な個所があったらダメ」という内容です。
なので、ここに書いてあることを「どうせいっぺんに聞いても分からないから」と覚悟のない姿勢で学ぼうとすると、結局はVBAの上達は望めませんので、もうそれなら最初からやらないほうがいいです。
もちろん、現実には「いっぺんに聞いても分からない」ということが起こってくるわけなんですが、でも、そこをあきらめないで、コツコツやりぬく気概が必要です。その「覚悟」です。
なので、繰り返しになりますが、ここの記事を学びきる気概と時間がないなら、(マジで「嫌味」ではなくて)最初からVBAはあきらめて、高校生や大学生、個人事業主などに安く作ってもらうことを考えるほうがはるかにあなたのお仕事のコスパをアップし、意味のあることになると思います。(特に時間の無い方・お忙しい方は。)
特に短期間に独学したい人へ→→→VBAの「独学」は、あなたの時間やお金を確実に「無駄に」奪います。
ある意味、「PCごとき、人間様が必ずねじ伏せてやる」という覚悟のある人や、「ヒマ人」とか、しかやってはいけません。
覚悟のない人やお忙しいかたは「もし確実なコスパアップが欲しいなら」、独学はやってはいけません。
ご注意ください。
逆に、(マイペースでいいので)やりぬく覚悟ができる人は、ぜひ、頑張ってみてください。
必ずいいことがあります。
覚悟をするだけでいいといえばそうだし、覚悟をしてコツコツ頑張れば、かならず、いいことがあります。
副収入とか・・・(^^)
(学習には、スタートダッシュ、勢い、も割と大事ですので、あえて厳しい感じのことを書かせて頂いてしまいました。すみません。本当はマイペースでもかまいません。)
※当然、「気長にゆっくりやれるから・・・という方」なら話は別です。本記事のことをゆっくりマイペースで学んだり、先生に質問してくだされば、かならず、中級以上に上がれます。
(A)本記事の目的
「独学」であっても、
できるだけ自力で、ラクに、「中級」にあがるため。
「独学」であっても、
初心者が中級者に、できるだけラクにあがるためのサポート。
▼「中級」とは?
△ヘルプを自力で読める。
△オブジェクトブラウザを自力で活用できる。
△ヘルプとオブジェクトブラウザが自力で活用できるから以下のことができる
・自力でエラーが解決できる。
・1回作ったプログラムをできるだけ何度も使いまわせる。
・1回作ったプログラムをできるだけ何度も使いまわせるように、汎用に改造できる。
△「動的な表」と「静的な表」の区別がつく
△「Microsoft Query」や「ピボットテーブル」自体を通常操作ができる
△「SQL」について、基本中の基本だけでもなんとか意味がわかる
△Microsoft Queryやピボットの簡易的なVBA操作ができる
△「DAO、ADO、SQL」を使って、閉じたままのExcelファイルをVBAで読み書きできる
△AccessとExcelを「COMオートメーション」で連携できる
△コピペでいいので簡易的なAPI操作ができる
△グラフの簡易的なVBA操作ができる
※僕は最後の「グラフを簡易的に操作できる」ができないので、まだ中級ではありません。
=====================================
(B)なぜ「中級」に自力であがることにこだわるのか?(その目的にした理由)
・VBAを使うなら「中級」以上に上がらないと、「お仕事のコスパアップ」なんて夢のまた夢・・・になってしまうから。
・それに加えてお小遣い稼ぎしたりもできない。また、給与アップにもとても結び付かないから。
・今のWebページや市販書籍の情報だと、中級にあがろうとすると、とたんに難しく感じて挫折してしまうから。
・市販の初心者本や中級者本、Webサイトを読んだだけでは、とても中級に上がれないから。(教える側の姿勢として「中級にあがるために何が必要か?」などが示されておらす、「やってるうちにわかるよ」という態度ばかりだから)
・市販の初心者本や中級者本、Webサイトを読んだだけでは、とてもヘルプを読みこなせないから。
・市販の初心者本や中級者本、Webサイトを読んだだけでは、オブジェクトブラウザの活用すらできないから。
・ひいては、エラーすら自力の解決ができないから。
・今の市販の初心者本や中級者本、Webサイトを読んだだけでは、それぞれの情報が「初心者目線としては」断片的過ぎて、「VBAの全体像」が「いつまでたってもつかめない」ので結局挫折しやすくなり、「いつまでたっても初心者から脱却できないまま」になってしまうから。
もっとも大きな原因は、僕自身、今現在ExcelVBAを独学中なのですが、その独学者目線から言うと、Web情報にしても市販書籍にしても、(恐らくVBA講習会にしても)、「そもそも教習の最初の時点で、オブジェクトの階層構造全体図を使わないから」・かつ・「それが ”かなり重要度が高い” ということをまったく教わらないから」だと思います。
また、「プロパティ・メソッド・イベント・ユーザー入力値・階層自由往来機能」などは「すべて ”オブジェクトの中” に保持・内包されている」ということすらも教えてもらえてません。
これは「生徒目線」・「教えてもらう立場」からすると、つくづくそう思います。
「オブジェクトが階層構造になっている」・「オブジェクトに内包されているものは何なのか?」・「オブジェクト変数に代入されるものは結局何か?」などについてすら最初に教えられていないのに、オブジェクトやオブジェクト変数や自作関数などが自由に扱えるわけがないと思います。ExcelVBAに対する理解が深まるわけがないと思います。
なぜ、ほんの一部のVBA講師さんを除く多くのVBA講師さんたちが(もうExcelが出て20年以上も経っているのに)そのような状況をいまだに放置しているのか僕には全く理解できません。
先生選びたいわ、と思ってしまいます。
なぜ「ヘルプを自力で読めるような指導」をしてくださらないのか、本当に理解に苦しみます。
つくづく、教えてもらう立場からすれば、「先生選びたいわ」、と思ってしまいます。
あと、基本的に、「基本」がしっかりしていれば具体的に次のようなメリットがあるから。
(a)ヘルプが読めるようになるので、エラーが出ても自力で解決できるようになる。
あるいは、ヘルプが読めることでエラー解決が早くなる。
(b)『マクロの記録機能でオブジェクトを調べても、必要なオブジェクト式の書き方がわからないとき』に、なんとか自力でオブジェクト式が書けるケースが増える。
(c)Webでオブジェクトのことを調べても自分の欲しい情報が無かった時に、自力でオブジェクト式が書けるケースが増える。
(d)「Web検索でヒットした情報は、そもそも、自分が探しているWeb情報なのか?」の判断がすごく早くなるので探す時間がすごく減る。
そもそも、何を検索したらいいかがすぐにわかる。検索の範囲も意図的に狭くできる。
(e)APIやSQL、DAO・ADO、なども多少使えるようになるため、共用部品を作る力がアップする。それによるコスパのアップがしやすくなる。
(e)「マクロの記録」で作ったプログラムを「汎用」に作り替えたり、それをアドインメニュー化したり、汎用部品・共用部品を作るヒントにすぐにできる。
特に、「マクロの記録」で作ったプログラムを部分的にでも「汎用」に作り足したり・作り替えたり、ということができると、忙しい時のコスパアップや、ユーザーのExcel習熟度別の対応、あるいは、「そのプログラムを本当に汎用化する価値があるかを判断するまでのテスト運用・テスト稼働・テスト利用・コスパアップ」にも貢献できる場合がある。
(f)以上のようなシーンが増えるので、短期間のうちに、中級の中・以上の腕前になれやすい。
(g)結果、コスパが良くなるシーンが増える。(最初は微増かもしれないけど)
(h)例えば有料で習いに行ったとしても、講習費用をできるだけ短期間に回収できる・・・、くらいの腕前になれる。
=====================================
(C)VBAプログラミングの中級にあがるために必要なこと(重要度順)
(01-1)プログラミングとは?VBAとは?(A図)
この図は、初級の方がスムーズに中級にあがれるようになるために、基礎中の基礎である、「プログラムを作るとは?」「VBAプログラミングとは?」ということについてまとめてあります。特にExcelVBAを想定して書いてあります。
と同時に、『(プログラムの最小単位である)「プロシージャ」の中にどんな要素を書き込むか?」の一覧図 』にもなっています。
(基本、エンドユーザー自身が手作業で書くプロシージャは、これらの要素を全部使うことが多いです。一方、「マクロの自動記録」で自動生成されたプロシージャはこのうちの一部か使いません。たとえば「オブジェクト・プロパティ・メソッド・列挙(&定数)のみがほとんどで、変数も関数もステートメント(≒条件分岐文や繰返文)も何もない・・・」という感じになります。)
※ただし、演算子と列挙(列挙体・列挙型・Enum)、あと、定数などのことを書き忘れましたので、でも、そちらはご自分でもどこに位置するか考えてみてください。
この図は、「今、自分が読んでいる書籍やWebサイトは、どこのことを言っているのか?」「この書籍やWebサイトに書いてあるほかに、最低限何を学ばないといけないのか?」などの現状確認・位置確認にぜひご活用ください。
そして基本、「この図の中で、 ”ひとことでも・一語でも一句でも” 意味が分からないことがあったら、VBAの中級以上への上達は ”100%” ”のぞめない”」です。
もちろん、初級から中級に上がる段階の方でなく、「超」初心者の方にも「特に有効」です。
そういう方がたにとってはこの図は「VBAプログラミング全体としての地図」とか、「プロシージャの中に書くものの地図」、「自分が今どの部分を学んでいるのかの地図」でもあります。
ですので、ぜひ、(繰り返しになりますが)「この図の中で意味がわからないことがあったら、VBAの上達はのぞめない」という風に意識して頂いて、この図の中の「わからないところ」を潰す・消す作業から入ってみてください。この図の中の「意味のわからないところ」を先生に聞きまくる、とか、Webで調べまくる、といった使い方をしてみてください。
一般的に、「プログラミング」とは、「変数」というものを思い通りに動かすことで「自動化を実現する」作業です。
そしてVBAプログラミングの場合、「変数」には大きくは「2種類」あります。
「一般的な変数」と「オブジェクト変数」の2つです。
※オブジェクトを動かすシーンでは、現実には「オブジェクト変数」のかわりに、「オブジェクト式(生のオブジェクト=変数に代入しないオブジェクト)」によるオブジェクト操作のほうが多くて、そちらが主流なのですが、「本来はオブジェクト変数を動かすほうがいい」と考えてしまうほうが「全体がすっきりする」と思います。
そのほうが「だからもっともっとオブジェクトに関する指導・教習をせねばならない。」となり、実際、初期の段階でもっとオブジェクト変数やオブジェクトやプロパティ・イベントの構造などつについてレクチャされたほうが、我々ド素人は、自分自身も、もっと能動的に成長を早められるし、挫折の回数もすごく減らせると思います。
そして本当に疑問なのが、どうして、ExcelVBAのプロの講師さんたちが、「VBAオブジェクト大図鑑」といった感じの本を出さないのかがさっぱりわかりません。
オブジェクトブラウザとヘルプの連携技、ヘルプの読み方、オブジェクトモデルの階層構造図の全体図、オブジェクトが保持する「プロパティ、メソッド、イベント、列挙」など、もっともっと初心者にわかりやすく説明してほしいです。
僕は、Excelのプロ講師さんたちが、まずExcelの画面やメニューの絵がまずあって、で、その横に、「このメニューや画面・機能・ダイアログはこのオブジェクト。そしてこのダイアログの中のこの設定はこのオブジェクト。設定項目はこの列挙。この操作はこのメソッド。そしてそれらでそういうことができる」という感じでいろんな説明がド素人にもわかるように書いてある、まさに、「オブジェクトとオブジェクト変数のことだけの」「ExcelVBAオブジェクト大図鑑」を書いてほしいと思います。
それを書かないってことは、もとから教える気が無いか、出し惜しみして「レベルの低いところでラクに儲けようと」、ラクして儲けようとしてるんじゃないか?と疑います。
ある意味、「一番肝心なことを”あえて”教えない、手抜き教習」。
Excelが出て20年もたったのに、そういう本がほとんどない(というか僕は一冊も知らない)、というのは、そういう、教える側・業界全体の怠慢ではないか・・・?と、本当に真面目にそう思います。
最近やっとExcelVBAに目覚めた、いち、ド素人のエンドユーザーの感想としましては。
20年もあったら、だれか一人くらいそういう本出すでしょ?ふつう・・・とか思ってしまいます。
それやらないから、低レベルなとこで、いまだにみんな挫折するのではないでしょうか?
いつまでたってもエラーが自力で解決できない・・・とか。
Q&Aサイトで聞いても結局意味が理解できず、絆創膏貼るだけの対応しかできない・・・。
もう日本の国際競争力のことやお若い方々の将来やプログラミングの一般教科化のことを真面目に考えたら、自分のホームページで無料Tips公開バンバンせずに、あいも変わらず低レベルなこと(例えば定型ビジネス集計とか)でお金とるExcelVBA講師は「プロの教える人」とは呼べない時代になったのでは?ある意味ぼったくりに近いのでは?と思います。
(01-2)Excel・Word・AccessVBAと「ユーザー別(あるいは役職別)セキュリティ」について
特にAccessのmdb拡張子のファイルは要注意です。
一応、「ユーザー別(あるいは役職別)セキュリティ」はかけられますけど、でも、万が一mdbファイルやユーザー別セキュリティの機能自体が壊れた時にデータが消滅する危険もありますので、使わないほうがいいです。(たいてい、ユーザー別セキュリティ機能だけが壊れた時に限って、バックアップ取り忘れたりするので)
ExcelやWordのファイルは、もし社内のどこかに「ユーザー別セキュリティの機能が組み込まれたシステム」があれば、そこに保管します。(もちろん「保管できる仕様なら」・・・ですが。)
ExcelやWord自身で、マクロ等々にてユーザー別セキュリティをかけようとしてしまうと、コスパが恐ろしく悪くなりますので、基本、ユーザー別セキュリティは最初からある意味、「捨て」、ます。
(もし誰か殊勝な方がExcel版でユーザー別セキュリティ機能を作ってくれたとしても、メンテが大変になることが想定されますので、結局はやらないほうが無難かと・・・。メンテも超ラクなモジュールならいいのかもしれませんけど・・・。多分、そんなことはできません・・・。)
Excelでミニシステムめいたものを、もし作ったときも要注意です。
絶対に「ユーザー別セキュリティの機能」なんて作り足さないほうがいいです。(特にプロじゃない人がシステムを自作する場合は。絶対にやめたほうがいいです。)
改修もすごく面倒くさくなり、コストばっかりかかって、その分の見返りはほとんどありません。
Accessの場合も、捨て、ます。(特にmdb拡張子の場合)
(ただし、Access場合は、ADPという拡張子のファイルの場合で、SQLサーバーなどに接続して使う場合は、「ユーザー別(あるいは役職別)セキュリティ」は確保できるようです。でもこちらもmdb同様に古い技術ですし、難易度が高いので、基本、自分でやるということは あきらめたほうが早いは早いです。専門業者に相談するほうがよいです。)
もしやむをえない状況で、かつ、使えるくらい小さな規模だったり、その他たまたま使える状況であれば、そのときだけ、慎重に、使います。
ただし、世代バックアップは必須です。
「ユーザー別(あるいは役職別)セキュリティ」は、Excel・Word・Accessでは「色んな意味でトラブルのもと」ですので、基本は、「捨て」、です。
(02-1)「プログラムの最小単位(=プロシージャ)」についての簡単な説明
A4印刷用PDF
● 「プロシージャ(プログラムの最小単位)」を書く場所についての早見表
↑ Ctrlキーを押しながらマウスのホイールを回して、拡大して見てみてください。
文字がおおきくはっきりと見えてきます。
(Ctrlキーを押しながら、+キーや-キーを押してでも拡大縮小ができます。)
プロシージャには以下のような3つの種類があります。
(b)Subプロシージャ(ある意味メインプロシージャ)
(c)Functionプロシージャ
(e)Propertyプロシージャ
・・・が、もうすこし現実的に分類すると次のような感じになります。
以下の(a)~(e)ように分類するほうが、VBAの全体像がつかみやすくなると思います。
これはAccessでもWordでも基本的には同じです。(Accessは「マクロ」の概念が少しExcelやWordとは違いますが、似てはいます。)
(a)イベントプロシージャ
ただし、シート上に配置したコマンドボタン等々や、シートそのものが保持するイベントに対してのみにしか書けません。なお、イベントプロシージャは「Subプロシージャの一種」です。(「開発」タブの「マクロ」メニューからは呼び出せません)
(b)Subプロシージャ(ある意味メインプロシージャです。「開発」タブの「マクロ」メニューから呼び出せます。)
(c)値またはオブジェクトを返さないFunctionプロシージャ
※値・・・「一般データ・文字ベースのデータ・文字系データ」のことです。
=「文字列、数値、日付、True/Falseの2値、など」です。
≒「リテラル値」ともとらえられます。
(d)値またはオブジェクトを返すFunctionプロシージャ
(e)Propertyプロシージャ
※基本、「開発」タブの「マクロ」メニューから呼び出せるのは「Sub プロシージャ」だけです。ほかのものは呼び出せません。
※(d)のうち、「値を返すFunctionプロシージャ」は、ワークシートの数式から呼び出すことができます。(=数式の中でワークシート関数と同様に扱えます。オブジェクトを返すものは使えません。)
Subプロシージャは「Sub プロシージャ名()」で始まり、「End Sub」で終わります。
「Sub プロシージャ名()」~「End Sub」のあいだに、実際のプログラムを書いていきます。下図のような感じです。
Functionプロシージャは「Function プロシージャ名(引数)」で始まり、「End Function」で終わります。下図のような感じです。
(↓こちらは「値またはオブジェクトを ”返さない” Funtionプロシージャ」の例です。)
Propertyプロシージャは「Property プロシージャ名()」で始まり、「End Property」で終わります。
SubプロシージャやFunctionプロシージャと同様なので、図は省略します。
・「開発」タブの出し方(2010以降)
Office アプリケーションで [開発] タブを表示する
[ファイル] タブ→→[オプション] →→[リボンのユーザー設定]→→[リボンのユーザー設定] および [メイン タブ] の下の [開発] チェック ボックスをオンにします。→→OK
・「開発」タブの出し方(2007)
Officeボタン→→「Excelのオプション」ボタン→→左ペインの「基本設定」→→『「開発」タブをリボンに表示する』をクリック→→OK
・VBE(Visual Basic Editor )の出しかた(2007以降、2003以前)
基本、両方とも Alt+F11キーで表示できます。
ただし、Excel2007以降の場合は、「開発」タブを表示させてからのほうがいいと思います。
Excel2003以前は、VisualBasicのツールバーを表示させてからのほうがいいと思います。
手動では以下の通りです。
2007以降→→「開発」タブ→→「Visual Basic」ボタン
2003以前→→ツール→→マクロ→→「Visual Basic Editor」
(03-1)「プログラムの最小単位(=プロシージャ)」を「書く場所=モジュール」、についての簡単な説明
前項でご説明した(a)~(e)の「プログラムの最小単位(=プロシージャ)」は、「モジュール」と呼ばれる白紙のシートに書きます。
例えば下図は、「白紙の用紙のようなもの」が画面の右側に大きく表示されています。
これが「モジュール」の中身です。
上図の例では、「Sheet1」に紐ついたモジュールの中身が表示されています。
そして「モジュール」には以下の種類があります。
(a)シートモジュール(複数作れます)
(b)ブックモジュール(これだけ複数は作れません)
(c)ユーザーフォームモジュール(複数作れます)
(d)標準モジュール(複数作れます)
(e)クラスモジュール(複数作れます)
(a)~(c)は、総称として「クラスオブジェクトモジュール」と呼ぶこともあります。
呼んでないサイトや市販書籍もありますが、でもその方がVBA全体を理解しやすいので、当サイトでもそう呼んでいます。また、Accessでもそう呼ぶので統一感がありますから。
あと、「クラスオブジェクトモジュール」はそれぞれのシート、ブック、ユーザーフォームを作った瞬間に、Excelが、それに1対1で紐ついたモジュールを自動的に生成してくれます。
それに対して、標準モジュールやクラスモジュールはユーザーが手作業で追加(=挿入と呼ばれています)します。
なお、「マクロの記録」機能では自動的に「Subプロシージャ」が生成されますが、その際、自動的に標準モジュールが生成されて、その中に「記録した内容の Subプロシージャ」が生成される格好となります。
※ (a)~(e)の実物については、VBE(Visual Basic Editor)の画面でも確認できます。
↓こちらの図(PDF)もご参照ください。(A4用紙1枚に横に印刷できます)
↑ Ctrlキーを押しながらマウスのホイールを回して、拡大して見てみてください。
文字がおおきくはっきりと見えてきます。
(Ctrlキーを押しながら、+キーや-キーを押してでも拡大縮小ができます。)
(03-2-1)プロシージャを書く場所01~クラスオブジェクトモジュール(シート、ブック、フォーム)
前項(03-1)のうち、(a)~(c)はExcelやWordでは「クラスオブジェクトモジュール」と呼ぶ人も居ます。
当サイトでもそのほうがVBAの全体像を理解しやすいのでそう呼んでいます。
Accessでは完全に(a)~(c)のようなモジュールを「クラスオブジェクトモジュール」と呼ぶことが多いです。Accessではフォーム(Excelの ”ユーザーフォーム” に相当。)やレポートなどのオブジェクトを完全に、「クラスオブジェクト」と呼んでいるからです。
(下図やこちらを参照)
また、「クラスオブジェクトモジュール」は(e)の「クラスモジュール」と少し似た感じの「立場」(?)です。
(「特定のオブジェクトのためのモジュール」「特定のオブジェクトと1対1で紐付いているモジュール」・・・という意味で、だけですが・・・。標準モジュールは特定のオブジェクトとは結び付いていません。)
「クラスオブジェクトモジュール」は「個々のシートやブック、ユーザーフォーム」と1対1で、
「クラスモジュール」は「自作のオブジェクト」と1対1で、
紐付き合っています。
(a)~(c)、は僕が勝手に言ってる呼び方です。
が、同じ呼び方をする人もいます。
そう呼ぶほうがVBAの全体像を整理しやすいのでそう呼んでいます。
「クラスオブジェクトモジュール」もAccessを含めるとそう呼んだほうがVBAの全体像を整理しやすいのでそう呼んでいます。
シートモジュールはエンドユーザーがシートを新しく作った瞬間に、Excelが自動的に、そのシートに1対1で紐付いた白紙の状態の「シートモジュール」を自動生成してくれます。
ブックモジュールもブックを新規に作成した時点で、Excelが勝手に作ってくれます。
ユーザーフォームモジュールも同様です。
なお、(a)~(c)の「クラスオブジェクトモジュール」には「イベントプロシージャ(Subプロシージャの仲間)」というものが書けますが、(d)と(e)には書けません。
※「イベントプロシージャ」は「あらかじめ定められたタイミングで自動実行ができるプロシージャ」です。特定のタイミング(≒イベント)とは、「クリックした時、セルの値を書き換えた時、フォームを開くとき」、などです。(a)~(c)それぞれに、「使えるイベント=あらかじめ定められたイベント」が異なります。
似た感じで、「クラスオブジェクトモジュール」では「Me」という「キーワード」と呼ばれるものを用いて、「自オブジェクトの記述を簡略化する」ということができます。例えば「Sheet1.・・・」とか「Worksheet(×××).・・・」と書くところを「Me.・・・」と書いてもOKです(つまり絶対指定ではなく相対指定な感じで書けます。が、これも(d)と(e)ではできません。エラーになります。
これはAccessのフォームやレポートでも同じです。フォームやレポートに紐ついたモジュールではMeが使えますが、標準モジュールやクラスモジュールではエラーになります。
(03-2-2)プロシージャを書く場所02~標準モジュール
あと、(d)は、通常はユーザーが手作業で追加(挿入・表示)するものですが、「マクロの自動記録」機能を使うと、Excelが自動的に追加(挿入)してくれます。記録されたマクロは、その中に「Subプロシージャ」として自動的に書き込まれます。)
基本的には、前項の図を参照してみてください。
(03-2-3)プロシージャを書く場所03~クラスモジュール
(03-3)「Propertyプロシージャを使う」「クラスモジュールを使う」の意味
「クラスモジュールを使う」とは、「オブジェクトを自作する」という意味ととらえていいと思います。
ただ、初心者、中級者はまず使いません。
その理由のひとつが次項です。次項をお読みになってみてください。
(もちろん、あくまでも「理由の」「ひとつ」ですので、ほかにもっとあると思います。)
※「Propertyプロシージャ」は「クラスモジュールを使って」「自作のオブジェクトを作る際に」、「そのオブジェクトに内包させる」ための、「プロパティ」を自作するためのプロシージャです。SubプロシージャやFunctionと比較すると少し特殊なものとなります。
なお、「クラスモジュール」では、プロパティのほかに、メソッドやイベントも自作できます。
「クラスモジュール」の中で「値を返すFunctionプロシージャ」などを使えば、「値を返すメソッド」などを作れます。
(03-4)「表の操作」に関してだけは「クラスモジュール」はそれほど必要ないと思います。多分。
Web記事や市販書籍などで「クラスモジュール」のことが書いてある部分を読むと、『「表」を「クラスモジュール」でオブジェクト化してプロパティなどを自作すると楽ですよ』、みたいな内容が多いです。
が、実際には、「お仕事のシーンでは」、『「表」をクラスモジュールオブジェクト化してプロパティなどを自作する』という作業はかえって手間だったり、無駄だったりすることも決して少なくないと思います。
(「表」の場合に限っては無理に「クラスモジュール」化しても扱いづらくなることが意外と多い気がします。あくまでも「表を扱う場合だけ」ですけど・・・。)
理由は、クラスモジュールで『 表をオブジェクト化してプロパティなどを自作する』よりも、以下の(ア)や(イ)の方法を使って「表をオブジェクト化」したほうが、「いろんな意味で」例えばメンテ等々に関しても効率がいいと思うからです。
(ア)「名前の定義」で定義したセル範囲を使う
(イ)DAOやADO+ループ処理(またはSQL)などで表やデータを操作する((ア)もまじえつつ)
また、上記の(ア)(イ)の方策をとるほうがクラスモジュールをいちいち使うよりも多分簡単で応用も幅広いです。
そしてDAOやADOを使うことは、プログラムを作ったあとのプログラムの可読性についても「クラスモジュールでプロパティを使ったりすること」と同等か、それ以上の可読性になります。(可読性→読んだ時の意味の把握のしやすさ、です)
また、DAOやADOでは「表をオブジェクト化」することが元々可能で、その「オブジェクト化した表(つまり、オブジェクト)」がそのままExcelVBAのルールと同じ感じで使えてしまいます。
そして、その「DAOやADOでオブジェクト化した以上のオブジェクト」を、わざわざ自分でクラスモジュールで自作するなんていうのは、マジで大変な・恐ろしく想像を絶する難易度です。
つまり、「表を扱う場面」でだけは、自分でクラスモジュールでオブジェクトを自作することは、その多くが「無駄な作業」となります。
さらに、特に(イ)のほうは、閉じたxls、xlsx、xlsm、のデータを「閉じたまま」読み書きできます。
『「表」をオブジェクト化してプロパティなどを自作する』ことを学習してもそれはできません。(もちろん学習すればしただけ絶対に無駄にはなりませんので、さらっとやっておくことは推奨いたします。僕もさらっとやって、この結論に達しました。さらっとやっておけば、「例外的に表をクラスモジュール化すること」が便利に使えるケースも知ることができると思います。)
ただし、『「表」をクラスモジュールでオブジェクト化してプロパティなどを自作するのはかえって効率が悪い』というのは、「あくまでも表を扱う場合のみ」です。
それ以外、たとえば、Excelゲームなどで複数のキャラクターを同時に動かしたり、などの場合は、多分、『「キャラ」をオブジェクト化してプロパティなどを自作する』ほうが確実に効率がいいのだと思います。
(あるいはグラフ操作でシェイプをいっぺんにたくさん動かしたいときや、ガントチャートをうようよいっぺんに動かしたいときとか、シェイプやドラッグを多用する座席予約ソフトを作るような場合、など。?かな?わかんないですけど。)
というわけで、中級者になっても、クラスモジュールは、たとえば一般的な「事務のお仕事」としては、さほど使わないと思います。(特に「ビジネス定型集計やリストアップ」では、どうしても、という場合以外はまず使う必要性がありません。)
つまり、中級者はクラスモジュールの学習は、基本的にはさほどしなくていいと思います。
(上級者だけがクラスモジュールを学べばいいと思いますし、中級者はそれよりも初級の内容の再確認や「基礎」の再勉強のほうが大切です。また、「表の操作に関してだけ」は、先にDAOやADOやSQLを覚えるほうがクラスモジュールで何かやるよりも、(Excel以外にも)ほかにいろんな場面で使えるため、はるかに効率がいいです。
「表」を扱うことに限定すれば、クラスモジュールの利用よりも、「SQLやDAOやADO」のほうがより「基礎」です。
「基礎」をないがしろにして、応用が、効率が良くなるわけもありませんし、「逆に基礎がしっかりしていればいるほど応用のときの効率が高まる」ので、クラスモジュールのことよりも「SQLやDAOやADO」のほうを先に「ある程度・困らない程度にマスターする」ことをおすすめします。
クラスモジュールのことは、特別な事情が無い限り、そのあとに本格的な勉強を始めても「まったく遅くはない」と思います。(お仕事で必要な際も、本当にクラスモジュールが必要かを再考してからでいいと思います。それでも緊急に必要なら、いますぐクラスモジュールについての学習を始めたらよいと思います。)
「Microsoft Office 以外のソフトも含めた事務のお仕事全体」で考えると、クラスモジュールのことよりも先に「SQLやDAOやADO」のほうを先にマスターするほうが、おそらく30~100倍は効率がいいと思います。
それでも「やれない」場合のみ、クラスモジュールでもし解決できるなら、クラスモジュールを使ってみてください。むやみにクラスモジュールを使っても、他の人がそのプログラムをメンテするときに、独自のそのクラスのことを覚えないといけないし無駄になるだけです。
DAOやADOやSQLを使えば、多くのデータ管理系のソフトで使える「汎用ルール」を覚えるだけなので・ある意味「公用語に近い」ので、より効率が高まります。(僕もそういう感じで今、独学していますです。)
【自作のオブジェクト、プロパティ、メソッド、イベント』については、すべてそういう考え方でよいと思いますです。(クラスモジュールを使うため)
Web記事には、「表をクラスモジュールでオブジェクト化するととても便利」とありますが、実際には名前付きのセル範囲やシート、テキストファイルなどをDAOやADOでオブジェクト化(レコードセット化)して、ループやSQLを使うほうが30~100倍は便利です。
ビジネス定型集計では「表をクラス化オブジェクト化する」ことが、DAOやADOを利用することよりも便利になるという事態は、あまりありません(僕はまったく思いつきません。無知なだけだとも思いますが)。
なので、そういう記事は基本、スルーして良いと思います。(何度も言いますが、もちろん学習すればしただけ絶対に無駄にはなりませんので、さらっとやって「どんな感じか」をつかんでおくことは推奨いたします。僕も実際にさらっとやってみてこれを書いています。)
何度も書きますが、「オートシェイプの多用やドラッグの多用など、ビジュアル重視のプログラムなどを作る場合や、チームで大きなプログラムを作るような場合」は、必要だと思いますので、その場合はもちろんクラスモジュールの学習をすぐに始めてください。
詳しくはプロのExcelVBAの講師さんにおききください。
(03-4-2)★★★★★ 必読!! ビジネス関連プログラムでの最大の要注意事項!!! Excelが間違う小数計算について(パソコンのバカさ加減について)とVariant型変数の多用の落とし穴について
パソコンは、状況によっては、「少数計算を間違う」のが「あたりまえ」というくらい、「バカ」な機械です。
そして、その場合、「小数点第1位の小数計算」すらもまともにできないです。
それくらい、「バカで頭が悪い」機械がパソコンです。
そしてそのとき「問題」となることがあるんですが、実は、Excelのセルはその計算間違い(すごく小さな微細な間違い)を見かけ上「勝手に丸めて」「正しくみせかけてしまう」ようです(バージョンによっても違うようですが)。
そのためユーザー(人間)は、「本当は計算間違いをしているのに」、「計算が正しい」と勘違いをしてしまいます。
しかし、「VBAプログラム」は「セルの」その「微細な計算間違いを見逃がしません」。
(セルの挙動とVBAプログラムは、基本的には独立しあっていて無関係なためです。)
だからそこで、「バグ」を生むことになります。
以下の記事にも詳しく書きましたのでご覧ください。
なお、以下の「参考URL」のWeb記事も必読ですので、必ず読んで、内容通りにVBAコードを実行してみてください。驚くべき「Excelのいい加減さ」がわかります。
(読むにはループ処理などのプログラムの基本を学んでからのほうがよいにはよいですが、でも、なんとなくでも「パソコンに対する警戒」や「 小数計算時の ” 慎重さ ” の大切さ」「安易なVariant型の多用のまずさ」「巷の講師たちの怠慢」を感じることができるかもしれませんので、ぜひ、学ぶ前であっても是非読んでみてください。
参考URL
『 Excel で実数を扱うときの注意 セルの謎 』
(全バージョンで。ただし、当方では未確認です。2010と2000には当てはまることが確認できました。)
『 Excel VBA プログラミング 「自動型変換」に関する落とし穴 』
(全バージョンで。ただし、当方では未確認です。2010と2000には当てはまることが確認できました。)
『 Excel VBA プログラミング 実数を扱うときの落とし穴 』
(2010では起こらず、2000では起こることが確認できました。おそらく2003か2007までは起こり、2007か2010以降は起こらないのではないかと推測しています。)
またVariant型の変数は、何らかの値やオブジェクトを代入したときに「勝手にデータ型を変換」します。たとえば・・・、
▼「ExcelやWordなどのユーザーフォーム」「Accessフォーム」上に配置したテキストボックスの値を代入すると、「それが数字や小数であっても ” 文字列 ” として勝手にデータ型の変換をしてしまい」ます。
▼InputBoxなどで代入された数字や小数も、同じように「 ” 文字列 ” として勝手にデータ型の変換をしてしまい」ます。これは関数の「戻り値のデータ型」が原因ですが、同じようなことが、
「関数が返すオブジェクトの型」、
「メソッドが返す文字列系データのデータ型」、
「メソッドが返すオブジェクトの型」、
「プロパティが返す文字列系データのデータ型」、
「プロパティが返すオブジェクトの型」、
にも言えます。
よって、Variant型の変数を扱う場合は、常に・・・
「関数・メソッド・プロパティ」を使う場合は、それらが返してくるデータの型をつねに調べ、意識する。(=勝手な思い込み・決めつけをなくすことでバグやエラーをなくす)とか、
「データの型が間違って勝手に変換されていないか、やローカルウィンドウ、TypeName関数、Parentプロパティ、などの使い方をよく学んでおく」
・・・等々の必要があります。
そのことを巷の講師たちはなぜか隠して教えてくれません。
少数計算についてもなぜか隠して教えてくれません。
『 ExcelVBAやAccessVBAのビジネス利用については必須なのに 』、それを 『知っているのに 』、です。
どうか彼らには騙されないようにご注意ください。
もちろん、僕の書いていることもあてにならないですので、安易に信じないで、常に、「自分でも調べる」ようにしてください。基本、「講師は都合の悪いことや面倒くさいことは隠す」と思って差し支えないです。もちろん信じることも必要ですが、意外とウソ教えられているケースも少なくないので、彼らが絶対、とは信じすぎないことも必要です。疑うことでバグやエラーから抜け出せることも少なくないです。
(03-4-3)「★★★★★★ 必読!! 要注意事項!!! オブジェクト式の「省略」が生むトラブルなどについて
ちょっと早いかもしれませんが、でも、「★★★ 人間様がサボるために超重要!!」というくらい大切なことを先にご紹介しておきます。
「どのプロシージャをどこからどのように呼び出せるか?」ということについてです。
このことは、「1回作ったプログラムをできるだけ多く使いまわして、無駄なプログラムを新しく作ってしまうことを減らす」ということに結び付きます。
このことを「最初に」教える書籍やWebサイトが少ないのですが(実は見たことないです)、逆に言うと、これを最初に教えないから「初心者の方々のための ”目的や道筋” が明確にならない」ということが言えます。
「これは初心者には難しいから後でいいだろう(そして結局 ”あと”にも教えない)」という教え方なので、初心者の方々は「中級に上がりたい場合にどこを目標にしたらいいか?」ということを念頭におけないまま、いわば「地図がないまま、富士の樹海をさまよう」ようなことになってしまいます。
「これは初心者には難しいからあとでいいだろう」ではなくて、「わからないに決まってるからこそ、でも、ならば、どこを目標にしたらいいか?」の、「マイルストーン」を初心者の方がたに示すべきです。
VBAプログラミングに限らず、「プログラミング教育」では、「やってるうちにわかるよ」という感じの教え方・・・、つまり「肝心なことを教えない教え方(ある意味詐欺)」が多いと思います。
これは20年前からまったくといっていいほど、変わってないのではないでしょうか?
だから挫折する人があとをたたない、のだと思います。
特に独学で。
Excelが出てから20年も経っているのですから、たとえば・・・、
・オブジェクト階層構造全図、
・ヘルプの読み方、
・オブジェクトブラウザの使い方、
・一般変数とオブジェクト変数
・値を返す自作関数とオブジェクトを返す自作関数
・イベントプロシージャをイベントが発生しなくても強制実行させる方法
・作ったプログラムの呼び出し方
・SQL、
・MicrosoftQueryのVBA操作、
・ピボットのVBA操作。
・ADO、DAO、とSQLなどを使った「閉じたExcelファイルの、閉じたままの読み書き」
・VBEのVBA操作
・・・といった基本は、「独学でも誰もが無料でWeb記事などによって半年以内に自動的に習得できる」状況になってないといけないはずです。
そして、有料の初級クラスは、グラフを高度に操作したり、シュミレーションプログラムの作成、ガントチャートのようなドラッグや画像を多用するプログラムの作成、あるいは、ビジネス分析とプログラムについて、などが「最初の授業」になってないといけないはずです。
でも現実は違います。
いつまでたっても初級クラスは20年前と同じ内容です。
僕もそうですけど、教えてもらう側・客の立場からすれば、「教える側はこれまでの20年、何やってたんだ?」と思ってしまいます。
初心者や忙しい人に必要なのは、まずは「今は当然分からんでもいいから、でも、近い将来には最低限これは全部記憶しないとダメ・でないとやったところで100%挫折するしコスパアップなんていつまでたってもできない」という「学習範囲・守備範囲はどこか?」を明確に教えてもらうこと、だと思います。
本項目もそのうちのひとつです。
最初のうちは確かに意味が分からないかもしれませんが、でも、ここでの項目のことは「VBAプログラミングの中でも、”学習の目標のひとつ” として、トップクラスに非常に重要」なので、例えば以下のリンク先の項目の2つの図(ここでは特に2つめの図)を参考にしてみてください。
● 「プロシージャ(プログラムの最小単位)」を書く場所についての早見表
● 1回作ったプロシージャをどう呼び出せるか(どう使いまわせるか?・再利用できるか?どう人間がサボれるか?)の関連図
※両方の図とも、A4用紙を横にして1枚で印刷できるようにしてあります。
また、CTRL+マウスのホイールボタン上回しで拡大もできるので、文字がガタガタにならない状態での拡大表示もできます。
(29-1)プロシージャの種類とVBEとの関係
(30-1)モジュールとVBEとの関係
(30-2)SubプロシージャやFunctionプロシージャの呼び出しについて
(SubプロシージャやFunctionプロシージャの実行方法や実行できる場所について)
これは、「★★★ 人間様がサボるために超重要!!よりラクになるために・よりコスパをよくするために超重要!!!」です!!!
プログラムは「人間様がサボるために!」作るものです。
これら上記のの3項目も、前項の2つの図をよく読んでみてください。
ここでの2つの図の一語一句、どんな単語も、意味が分からない、ということがあったら、絶対に中級にはあがれません。どうか、この図の「わからないところを潰していく」という形でVBAの学習をしていってみてください。
※これ以外にも、本記事全体に表示されている図(PDF)はすべて、「一語一句すべて覚えないといけない」ことばかりです。
(04-1)実際の『「プログラムの最小単位=プロシージャ(=小さくて簡単なプログラム)」の書き方の流れ』の事例(もっとも簡単なプログラム x+y など。)
(05-1)プログラミングの操作対象:★★★「プログラムの汎用化=効率化」に大貢献する「変数」に対する簡単な理解01(「代入」とは?「=(イコール」の意味について)
変数はメモリ上に作成する、計算用の「空の仮箱」です。
小学生か中学生の時に習った、X+Y=Z の数式の「変数」と同じ意味合いです。
その時習ったのはたしか、数字を代入するための仮の入れもの、でしたよね?
それと同じです。
(プログラミングの場合は、数字だけでなく文字列や日付、オブジェクトと呼ばれるユニットも代入できてしまう仮箱ですが・・・)
変数は、ユーザーがメモリ上に好きに作成することができる、空の仮箱です。名前をつけることもできる仮箱なので、利用がしやすいです。
もう少し別の言い方で言うと、変数は「生データ」を代入できる「空の仮の箱」です。
料理でいうと、「素材」を仮乗せしておくための「小皿」です。
パソコンが得意な方なら、「データを加工する目的で、データを一時保管するためのクリップボードのようなもの」と言ったほうがわかりやすいかもしれませんね。
いずれにしましても、変数は「空の仮箱」ですので、「どんな値も代入することができます」。
・・・というわけで
変数は、
計算用・データ化効用・自動化用の「空の仮箱」である・・・・
ということと、
「どんな値も代入することができます」・・・・
という性質を持っているため、
これが
「プログラムを汎用化できる=1回作るだけでたとえば数十の多くのケースにあてはめて動かす・使う・自動化することができる」
ということに大きく貢献します。
言ってみれば、変数があるからこそ、「より多くの場面で」「人間様がサボる」・・・、ということが可能となると言っても過言ではありません。
「プログラム」は、「人間様がサボる」、ために作るものです。
「機械にやらせときゃいい作業なんて人間様がやりたくない」です。だから作る。それが「プログラム」です。
(プログラムによっては、「夢を増幅」させることができます。)
「変数」はその「最初」の「サボるための道具」「夢を増幅させるための道具」です。
プログラミングには、ほかにも「サボるための道具」「夢を増幅させるための道具」として、(後述しますが)「ステートメント(制御文)」というものがあります。
その中でも特に、「分岐」と「繰り返し」の制御構文が「サボるための道具」としてかなり強力です。
そちらはまたおいおい、お話いたします。
(06-1)プログラミングの操作対象:★★★「プログラムの汎用化=効率化」に大貢献する「変数」に対する簡単な理解02(一般変数とオブジェクト変数の区分やそれぞれの役割、さらに細かい種類、など)
(07-1)プログラミングの操作対象:★★★「プログラムの汎用化=効率化」に大貢献する「配列」について
(08-1)プログラミングの操作対象:「定数」についてと、VBA定数(?列挙体?)のイメージについて
(08-2)プログラミングの操作対象:「列挙型変数」について
↓こちらをご参照ください。
https://www.moug.net/tech/exvba/0150119.html
(09-1)変数を動かす道具たち:「予約語」とユーザーが付けられる名前について
関数や定数などの名前について
(10-1)変数を動かす道具たち:VBA関数について(数値・文字・日付などの文字ベースの各種の値の操作、ファイル操作、オブジェクト操作、など)
ワークシート関数とVBA関数の違い
オブジェクトブラウザ上では、ワークシート関数は「WorksheetFunction オブジェクト」のメソッドとして、VBA関数は、「DateTimeモジュール」や「FileSystemモジュール」、「Financialモジュール」「Conversionモジュール」「Mathモジュール」「Stringsモジュール」等々のメソッドとして表示されます。
(12-1)変数を動かす道具たち:「演算子」について
(ak)変数を動かす道具たち:ステートメントについて(一般変数もオブジェクト変数も共用する命令たち)
「★★人間様がさぼるための強い味方!!★」
→→→→→特に「繰り返し文(=ループ文)」
「マクロの自動記録には一切、自動生成・自動書き込みされない命令たち。」
(13-1)「★★人間様がさぼるための強い味方!!★」ステートメント01~変数宣言や代入の文
配列も
(14-1)「★★人間様がさぼるための強い味方!!★」ステートメント02~分岐処理の文
(15-1)「★★人間様がさぼるための強い味方!!★」ステートメント03~★★★★★★ 繰り返し処理の文
(16-1)「★★人間様がさぼるための強い味方!!★」ステートメント04~エラー対策の文
(17-1)「★★人間様がさぼるための強い味方!!★」ステートメント05~その他の文(Withとか)
各種の命令たちが、「変数の外側に居ようが内側に居ようが」、変数を動かすことに変わりはないので結局は大したことではないんですけど、ただ、それでもVBAプログラミングの全体像の把握の一助になれば・・・。
(19-1)「VBE(VisualBasic Editor)」の画面の簡単な説明
(20-1)シートのイベントプロシージャの簡単な作成事例とVBEについて
(20-2)シートのイベントプロシージャ、特に「Change」イベントで起こるイベントの無限連鎖
解決法
Application.EnableEvents = False
Application.EnableEvents = True
事例:https://teratail.com/questions/183373
(21-1)ユーザーフォームの簡単な作成事例とVBEについて
(22-1)「コントロール」について(オブジェクトとの違い、など)
(23-1)ユーザーフォーム上のコントロールのイベントプロシージャの簡単な作成事例とVBEについて
(24-1)「標準モジュール」の使い方
消し方、解放、インポート・エクスポート(バックアップ)
(25-1)「ワークシート関数」と「VBA関数」について
(26-1)「値を返す関数」とその自作について(オブジェクトブラウザの操作の理解に必須)
(27-1)「オブジェクトを返す関数」とその自作について(オブジェクトブラウザ操作の理解に必須)
(28-1)「マクロ」と「VBA」との違いについて
用語:ExcelやWordにおける「マクロ」とは?VBAと何が違う?(「ExcelやWord自身」は「マクロ」をどう判別・区別しているか?)Accessの場合は?
(29-1)プロシージャの種類とVBEとの関係
(30-1)モジュールとVBEとの関係
(30-2)SubプロシージャやFunctionプロシージャの呼び出しについて
(SubプロシージャやFunctionプロシージャの実行方法や実行できる場所について)
これは、「★★★ 人間様がサボるために超重要!!よりラクになるために・よりコスパをよくするために超重要!!!」です!!!
プログラムは「人間様がサボるために!」作るものです。
ここでの上記の3つの項目は、以下の2つのPDFをご参考にしてみてください。
VBA関連の書籍を読んでいるときに、自分がどの部分について読んでいるかを知るための「地図」のような感じでも使ってみてください。
VBE_プログラムを書く場所について.pdf
↑↓ Ctrlキーを押しながらマウスのホイールを回して、拡大して見てみてください。
文字がおおきくはっきりと見えてきます。
SubプロシージャやFunctionプロシージャの呼び出し可能方向(実行できる場所・方法)について.pdf
↑↓ Ctrlキーを押しながらマウスのホイールを回して、拡大して見てみてください。
文字がおおきくはっきりと見えてきます。
これらの2つの図は、SubプロシージャやFunctionプロシージャの呼び出しについて、「プロジェクトエクスプローラを直接用いた説明文書」が無いと思ったので作りました。(SubプロシージャやFunctionプロシージャの実行方法や実行できる場所について書いてあります。)
特に、SubプロシージャやFunctionプロシージャの呼び出しについては「どれだけ人間がサボってラクをするか」に関係が深いですし、中級に上がるとかヘルプやオブジェクトブラウザをちゃんと扱えるようになるには必須の知識ですので、必ずマスターする必要があります。
この2つのPDFに書かれていますことは、こちら のPDFとともに、VBAの基本中の基本の1つですので、分かる人に良く聞いて、すべてが理解できて僕のミス記述を指摘できるようになるまで、100回でも200回でも聞いて、マスターしてください。(至る所で間違いを犯していると思いますので)
でなければVBAをやる意味が無いので、最初からVBAなんかやらないで、誰か外注で安くやってくれる人を探したほうがいいです(学生さんとか)。イヤミではなく本当に「ムダ」で時間やお金がもったいないので、「”基本”をやる気や時間が無い」とか、「コスパを重視したい」という人・会社・お店さんは本当にそうしたほうがいいです。
この2つの図も、「オブジェクトとは?」を考える前の段階の、「プログラムを作るとは?」「VBAプログラミングとは?」ということの一環としてまとめてあります。
そのため、基本、「この図の中で意味がわからないことがあったら、VBAの上達は100%のぞめない」です。
なので「超」初心者の方もぜひ、読んでみてください。
そして、わからないことは、どんどん先生やわかる人に質問してみてください。
※絶対にこちらも読んでおいてください!! ↓↓↓
★★★★★★★★★★★★★★★★ 超重要!!必読!!ExcelVBAが上達するかどうかの最初の分かれ道!オブジェクトとオブジェクト式について~★★★★★★★★★★★★★★★★
少し詳しく、でもそこそこまとめた記事です。
(31-1)プログラミングの操作対象:「オブジェクト」の事例(実際の画面の各パーツやメニューとの関係)
(32-1)プログラミングの操作対象:「コントロール」について(ユーザーフォーム上とシート上)
AccessのフォームはExcelのユーザーフォームの操作と少し似ている
コントロールと呼ぶのは同じ。ただしAccessは表の上にコントロールは作れない。
Excelはシートの上にコントロールを作れます。
(33-1)プログラミングの操作対象:「コレクション(=コレクションオブジェクト)」について
(34-1)プログラミングの操作対象:「Enum・列挙型・列挙体・列挙」と「定数」について
各種設定ダイアログの、各種設定項目のドロップダウンの中の各種値が列挙体の各値になっているっぽいです。
※参考記事
Access2000VBA・Excel2000VBA独学~用語:”目に見える”「メソッド・プロパティ・列挙(=Enum)・定数(=Const)」と右クリックメニューの画面の関係について~
(35-1)プログラミングの操作対象:オブジェクトモデルの階層構造の理解(コレクション→単一オブジェクト→プロパティ、メソッド、イベント、ユーザー入力値、階層構造)
WorksheetオブジェクトやRangeオブジェクト、Chartオブジェクト、Shapeオブジェクトなどを例に。
5つの機能も含めた細かいところまで。
Application→コレクション→単一オブジェクト→プロパティ、メソッド、イベント、ユーザー入力値、階層構造
(36-1)プログラミングの操作対象:「オブジェクトの取得」の意味
(37-1)プログラミングの操作対象:「オブジェクトへの参照」の意味
(38-1)プログラミングの操作対象:「オブジェクトへの参照」の意味
(39-1)プログラミングの操作対象:すべてのオブジェクトはその1つひとつが「5つの機能」を保持している。(プロパティ・メソッド・イベント・ユーザー入力値・階層構造、は、厳密な説明を理解するより、どれも、全部、”オブジェクトが保持する「機能」たち”、と大雑把にとらえるほうが色々と理解しやすい)
(40-1)プログラミングの操作対象:「オブジェクトの取得」と「オブジェクト式」「部分オブジェクト式」について
(41-1)プログラミングの操作対象:「オブジェクトの取得」=「オブジェクト式の作成」=「オブジェクト式を書く作業」は、主に、番号でやるか、名前でやるか、列挙型の定数でやるか、の3パターンが多い。
(42-1)プログラミングの操作対象:オブジェクト変数と「真に代入されるのは”参照”」の意味についてと、でも「代入された=5つの機能が使える」と理解するほうが面倒くさくない、ということについて
(43-1)「5つの機能」はオブジェクトの内部に居座りつつ、オブジェクトを動かせる。
A図
(44-1)「関数」や「ステートメント」はオブジェクトの外側からオブジェクトを動かせる。
A図
(45-1)プログラミングの操作対象:「オブジェクト変数」について
(46-1)プログラミングの操作対象:「オブジェクト式」と、オブジェクト式を代入したオブジェクト変数」の関係について(イコール関係・その他の視点について)
(46-2)プログラミングの操作対象:「オブジェクト式」と、「部分オブジェクト式」について
(47-1)プログラミングの操作対象:「一般的な”コンテナ”の意味」、「ヘルプに書かれた”オブジェクト”としてのコンテナ(埋込オブジェクト:ガワ、の意味」について
(48-1)プログラミングの操作対象:ワークシートに埋め込まれたグラフの扱いとコンテナとVBEについて
(49-1)「セルの取得」「セル範囲の指定」「セルの選択」などについて
△「A1形式」でのセルの取得・範囲指定・選択
・基本、Rangeオブジェクト(絶対/相対)を使う
・ドラッグ選択単位での取得・範囲指定、というイメージ
・「1つのRangeプロパティ単独」で、「A1:F10」といった「範囲選択」ができる
・セルの縦方向のループ処理に使える。横方向は弱い。あまり使えない。横方向に処理したい場合は「For Each ~ Next文」が必要。「For Each ~ Next文」はExcel・Word・Accessのオブジェクトやコントロールだけでなく、DAOやADOのオブジェクトでも使えますので、使い方を覚えておくと便利です。
・「名前の定義」での「表の名前」も使える
△「R1C1形式でのセルの取得・範囲指定・選択
・基本、CELLSオブジェクト(絶対/相対)を使う
・単一セル単位での取得・範囲指定、というイメージ
・「1つのCellsプロパティ単独」では、「A1:F10」といった「範囲選択」ができない。(=Rangeオブジェクトを1階層上位=親に一つ、もってこないとできない)
・セルの縦方向のループ処理だけでなく縦方向のループ処理にも強い
・「名前の定義」での「表の名前」は使えない
(50-1)Rangeオブジェクト(セルの取得・選択)とヘルプの重要なことについて
2010のヘルプで「Range」という語句で検索すると以下のヘルプページへのリンクが出てきます。
全部で4ページ分くらい出てきますが、以下のものはその1ページ目だけの分です。
Range オブジェクト メンバー
Range オブジェクト(01)
Range オブジェクト(02)
Range プロパティ
Application.Range プロパティ
Worksheet.Range プロパティ
Range.Range プロパティ
Range.Cells プロパティ
GroupShapes.Range プロパティ
Shapes.Range プロパティ
Range.DirectDependents プロパティ
Range.DirectPrecedents プロパティ
Range.Item プロパティ
Range.Rows プロパティ
Range.Columns プロパティ
Range.End プロパティ
Range.CurrentRegion プロパティ
Range.Dependents プロパティ
Range.Precedents プロパティ
Range.Style プロパティ
Range.SortSpecial メソッド
Range.AutoFill メソッド
Range.Dirty メソッド
Range.ColumnDifferences メソッド
Range.Table メソッド
本当は、「セルの取得や範囲指定、選択等々」については、例えばですが、以上を含めた4ページ分のヘルプページをすべて読まないと、本当のところはわかりません。(実際にはそれら以外にももっと読まねばならないかもしれません)
でないと、いつまでたっても初心者を脱出できず、そのうちいやになって挫折してしまいます。
逆に、これらをすべて読んで半分くらいが理解ができれば、Webや市販書籍に書いてあることが間違いであるとか、「この段階でなら自分なりにこう考えてしまえば大丈夫」といった「考え方の基準」ができてきます。
それが、自力でのエラー解決やさらなる効率化に必ず・大いに貢献します。
結果的に、初心者を脱出できます。中級以上にスムーズに登っていくことができます。
また、「選択」はパソコン操作のスタートであり、「何がどう選択されているか」がわからなければ、パソコン操作は必ず行き詰ります。
それは、VBAプログラムでも同じです。
特にRangeオブジェクトは「選択」の意味が色濃いオブジェクトですので、パソコン操作の基礎と同様、「ExcelVBAの上達」には、ここをおろそかにはできません。
逆に言うと、ここをWebサイトや市販書籍にいいかげん・テキトーに説明されるため、「挫折する人があとをたたない」とも言えると思います。
また、習う側も、ここを「どうせいっぺんに聞いても分からないから」と覚悟のない姿勢で学ぼうとするため、いつまでたっても初心者を脱出できません。
実際には、この記事に書いてあることは基本中の基本であり、この記事に書かれたことがわからないなら、VBAは100%初級どまりで中級以上には上がれないです。この記事に書かれていることは「このなかの特にどれが重要」という話ではありませんで、「全部重要」「全部一語一句意味不明な個所があったらダメ」という内容です。Rangeオブジェクトのことはその中のほんの一部にしか過ぎないので、なので、ここを「いっぺんに聞いても分からないから」と覚悟のない姿勢で学ぼうとすると、結局はVBAの上達は望めませんので、最初からやらないほうがいいです。
ここの記事を学ぶ気概と時間がないなら、最初からVBAはあきらめて、高校生や大学生、個人事業主などに安く作ってもらうことを考えるほうがはるかにあなたのお仕事のコスパをアップし、意味のあることになると思います。
VBAの独学は、あなたの時間やお金を確実に奪います。
ある意味「ヒマ人」しかやってはいけません。
(50-2)RageプロパティとCellsプロパティの違いと「For Each ~Next 文」について(絶対/相対)
(51-1)「For Each ~Next 文」について
オブジェクト操作やオブジェクト変数操作に使う繰り返し文で、一括処理がしやすいです。
コレクションの中の単一オブジェクトをすべて、走査してしてくれますので、処理を適用したい・あるいは・したくない単一オブジェクトの条件を、IF文などで指定します。
コレクションだけでなく、セル範囲の中のすべてのセル、また、DAOやADOなどのオブジェクト(列とか)にも利用できます。
(一般変数=文字ベースデータの変数の繰り返し処理・一括処理には使えません。その場合は、「For i = ・・・Next i 文」などを使います。カウンタ用の変数も必要です。「For Each ~Next 文」ではカウンタ変数はコレクション内の単一オブジェクトたちに対しては、基本としては、必要ありません。)
なお、『「もともと一括処理用ができてしまうメソッド」では細かいところの操作ができない・・・』といった場合には、「For Each ~Next 文」のほうが便利なことも少なくないかもしれません。
適材適所で使えると思います。
◆超重要な注意!!!!
セルをVariant型の2次元配列に代入すると、For Each 文で各要素を(ループとして)回すときは、
下(行)方向が先で、そのあと右(列)方向に回ります。(列単位で回る)
しかし、配列に代入せず、そのままセル範囲を For Each 文で回すと、
右(列)方向が先で、そのあと下(行)方向に回ります。(行単位で回る)
ここは注意が必要です!!!!
※参考URL→https://www.relief.jp/docs/excel-vba-order-for-each-looping.html
また、配列のその縦横の並びを、「(新しいVariant型の変数を使って)・そのVariant型の変数の内部で」入れ替えるには、WorksheetFunction.Transpose を使うと良いようです。(以下の例をご参照ください。)
v_Rng01 = o_SrcWS.UsedRange '横方向に展開されたセルを代入した2次元配列を
v_Rng02 = WorksheetFunction.Transpose(v_Rng01) '縦方向の2次元配列に変換する
あるいは
新しい変数を用意しないなら、
v_Rng01 = o_SrcWS.UsedRange '横方向に展開されたセルを代入した2次元配列を
v_Rng01 = WorksheetFunction.Transpose(v_Rng01) '縦方向の2次元配列に変換する
(ちゃんと変換されたかをローカルウィンドウで確認したい場合は、前者のように変数を分けたほうがわかりやすいです。)
ついでですが、「WorksheetFunction.Transposeメソッド」は、「1列だけ・あるいは・1行だけ」の2次元配列であれば(それに限り??未チェックです)、「1次元配列」に一発変換することができます。
ただ、そのとき、
縦の1列分のセル範囲をVariant型の変数(自動的に2次元配列になる)に代入した時は、1回使えばいいですが、
横の1行のセル範囲を代入した時は、2回、使います。
なお、1次元配列になった瞬間に、縦のセル範囲のものが横になります。横のモノは横のままです。
(2次元配列は、縦にも横にもできます。)
(※後述のプログラム「test22()」もお試しください。どう操作したときに、どうセルに値が貼りつくのか、色々わかります。)
縦のセル範囲場合で、「1つの変数だけでやる=変数を上書きする」ときの例
v_Rng = Worksheets("Sheet2").Range("A1:A3")
v_Rng = WorksheetFunction.Transpose(v_Rng) 'いきなり一発で1次元配列に変わる。
ヨコのセル範囲の場合
v_Rng = Worksheets("Sheet2").Range("E1:G1")
v_Rng = WorksheetFunction.Transpose(v_Rng) 'いったん、縦の2次元配列に変わる
v_Rng = WorksheetFunction.Transpose(v_Rng) '1次元配列に変わる。
ローカルウィンドウでF8のステップ実行で、変数の中身の変化を確認してみてください。
ただ、これを見ると、逆に言うと、「1列だけ」のセル範囲をVariant型の配列に代入した際は、いきなり1次元配列に変わってしまうので、「それが原因でエラー」になるケースもあるかもしれません。ちょっと注意が必要かもしれません。
(52-1)ループ処理の構文を使わずに、セル=Rangeオブジェクトの一括処理(並べ替え・検索・データの書き換え、その他)ができるメソッドやプロパティ等々
ExcelVBAでは、「FOR~NEXTやDo~Loop、For Each 」といった、ループの構文を使わずに、「並べ替え・検索・その他」ができます。
別の言い方をすると、『カウンタ変数+繰り返し文やFor Each 文などを使わずとも、できるだけ色んな一括操作ができるように、そのためのメソッド(命令)が、VBAのオブジェクトにはもともと備え付けられている・・・』、ということでもあります。
この、「カウンタ変数+繰り返し文やFor Each 文などを使わずにいろんな一括操作ができるメソッド」は、無駄なプログラムコードを書くことを激減させてくれます。(もちろん For Each 文もとっても便利です。ただ、シーン別にそれ以外の方法として。)
なら、初心者は、そのようなメソッドをできるだけたくさん学ぶ必要があると思います。
先輩や講師の先生に、その点も是非、質問してみてください。
【一括選択】
(イ)Worksheet.UsedRange プロパティ
(UsedRange =現在使用されているセルのほぼすべてを取得(≒選択)。とびとびのセルであっても。)
「UsedRange」は、指定されたワークシートで使われたセル範囲 (Range オブジェクト) を返します。
具体的には、シート上においての「値や数式等の入ったすべてのセルたち」を俯瞰したとき、その一番左上のセルから、一番右下のセルを、「1つのくくり」として=「セル範囲」として、取得できます。
セルとセルのあいだに空白セルがあった場合は、それらもすべて含まれます。(見え方によっては表と表・あるいは・表と部分的なセルのあいだに存在する空白セルも同様です。すべて「UsedRange」の範囲の中に含まれます。)
なお、「UsedRange」とだけ書いてしまうと(つまり親オブジェクトを書かないと)、エラーになります。
必ず「どのシートの」UsedRangeなのかを書く必要があります。
例01:Activesheet.UsedRange.Clearcontents
'使用されたすべてのセルの、(書式設定は残したまま)数式と文字を削除。
'基本、消したくない列名なども容赦なく全部消えてしまいます。
'そのほか、値や数式の入ったセルに「シートの保護」などでロックがかかっているとエラーになります。
例02:ActiveSheet.UsedRange.Sort Range("A1"), xlAscending
'アクティブなシートの、使用されたすべてのセルを範囲として、A1セルの列を基準に昇順に並べ替え。
'ただしこの場合は列名も並べ替えられちゃいます。そうならないようにするには、
'ActiveSheet.UsedRange.Sort Range("A1"), xlAscending, Header:=xlYes という感じで、
'「, Header:=xlYes」を付け加えると、列名は並べ替え対象からはずされます。
'また、降順にするには、「xlAscending」を「xlDescending」に書き換えます。
'「UsedRange」の親オブジェクトとしての「ActiveSheet.」は省略できません。
'ヘルプには省略のことが何も書いてないし、実際省略すると「オブジェクトが必要です」の
'エラーになるためです。
'ただ、並べ替え基準列のほうの「Range("A1"),」は、「ActiveSheet.」は省略可能です。
'理由は、RangeプロパティでRangeオブジェクトを取得する場合は、親オブジェクトを省略すると
'作業中のワークシート(アクティブなワークシート)のセル範囲を対象とするからです。
'これはApplication.RangeやWorksheet.Rangeのヘルプに書いてあります。
※その他の指定方法
・Application.ActiveWorkbook.Worksheets(5).UsedRange
・ActiveWorkbook.Worksheets(5).UsedRange
・Worksheets(5).UsedRange
・ActiveSheet.UsedRange
(ロ)Worksheet.Range プロパティ、Application.Range プロパティ
通常のセルアドレスだけでなく、名前の定義で定義した名前も使うことができます。「Application.Range」の場合は、「Application.」を省略すると、ActiveSheet.Range のショートカットとなります。
例:Range("testtable").Sort Range("A1"), xlAscending, Header:=xlYes
'名前の定義で「testtable」と名付けた表(=セル範囲)をA1セルの列昇順に並べ替え。列名除外。
'「testtable」と名付けた表がアクティブなワークシートにある場合はこれでOKです。
'また、降順にするには、「xlAscending」を「xlDescending」に書き換えます。
(ハ)Range.CurrentRegion プロパティ
アクティブ セル領域 (Range オブジェクト) を操作できるようにします。アクティブ セル領域とは、空白行と空白列で囲まれたセル範囲です。
つまり、アクティブセルや単一の1つのセルをまず親として指定し、そのセルと隣接する「データの連続するエリア」を取得(=選択)してくれます・・・・、
・・・つまり、「指定した単一のセルを含む ”表”」などを取得してくれます。※”表”でなければ、空白列と空白行までのエリアとなります。そのため、UsedRangeプロパティやSelectプロパティのように、複数の表のエリアを同時取得することはできません。1つの表、というイメージの取得しかできません。)
例: Worksheets("sheet1").Range("A1").CurrentRegion.Copy
'シート1のA1を起点とした表範囲(というかセル範囲)をコピー
※その他の指定方法
・Application.ActiveWindow.ActiveCell.CurrentRegion
・ActiveWindow.ActiveCell.CurrentRegion
・ActiveCell.CurrentRegion
・Application.Worksheets("シート名").Range("C2").CurrentRegion
・Range("C2").CurrentRegion
※「Range.CurrentRegion」の「Range」の部分でActiveCellを使ったときは、その親オブジェクトに「ActiveSheet」や「WorkSheets(××)」を書くとなぜかエラーになります。ActiveWindowならOKです。イミディエイトウィンドウで「 ? TypeName(ActiveCell.Parent)」でEnterすると「WorkSheet」と出るので不思議なんですけど、ヘルプを読むと「アクティブ ウィンドウまたは指定されたウィンドウでのアクティブ セルを表す」とありActiveSheetのものではなさそうなので一応納得・・・。
また、CurrentRegionとだけ書いた場合もエラーになります。必ずRange(××)やActiveCellなどの親オブジェクトの記述が、最低限必要です。
あと、保護されたワークシートでは使うことができません。
ヘルプより→『 Range.CurrentRegionは、Rangeオブジェクトを返すプロパティです。アクティブ セル領域 (Range オブジェクト) を返します。アクティブ セル領域とは、空白行と空白列で囲まれたセル範囲です。値の取得のみ可能です。』
(ニ)Application.Selection プロパティ(ActiveWindow.Selection プロパティ)
セルをドラッグで選択した場合の、水色反転表示された部分を操作対象として取得してくれます。Ctrlキー+クリックやドラッグ、などで、飛び飛びに範囲を選択した場合は、その飛び飛びの状態が取得されます。「$A$1:$D$9,$H$8,$F$12,$J$4」といった感じでカンマで区切られて。
ただし、ActiveWindowsや指定した「ウィンドウ」の中での選択・・・という感じです。
「ActiveSheetの中の選択」という意味ではないので、親オブジェクトとしてはActiveSheetなどは使えません。
また、UsedRangeプロパティのように「範囲内の空白セルも含まれる」ということはありません。
繰り返しになりますが、Selectionプロパティ は、ウィンドウの中で現在選択されているオブジェクトを返してくれます。(シートの中の選択物・・・、という意味ではありません。)
返されるオブジェクトの種類は、今・何を選択するかによって異なります。たとえば、セルを選択しているときはRange オブジェクトが返されます。
何も選択していないときは Nothing が返されます。
このプロパティは、オブジェクト修飾子を指定せず使用した場合でも、Application.Selection と同様の結果になります。
例: Application.ActiveWindow.Selection.Copy
'アクティブウィンドウのドラッグで選択されたセル範囲をコピー
'飛び飛び選択ならそのままんま、そのセルたちだけをコピー
'埋め込みグラフが選択されていればそれをコピー
'複数のオートシェイプが同時選択されていれば、それをコピー
※その他の指定方法
・Application.ActiveWindow.Selection
・ActiveWindow.Selection
・Selection
・Application.Selection
【並べ替え】
(イ)Range.Sort メソッド(全バージョン)
例01:ActiveSheet.Range("A1:F30").Sort ActiveSheet.Range("A1"), xlAscending, Header:=xlYes
'セル範囲「A1:F30」をA1セルの列で、昇順に並べ替え(列名除外)
例02:Worksheets("sheet2").Range("testtable").Sort Worksheets("sheet2").Range("A1"), xlAscending, Header:=xlYes
'「Sheet2」がアクティブじゃなくても、「Sheet2」にて「testtable」と名前定義したセル範囲を、
'「Sheet2」の「A1」セルの列で昇順に。(列名除外)
'「定義した名前」を使って並べ替えするときは、先頭の「Worksheets("sheet2").」を
'省略してもエラーにならないようです。名前の定義の中で「Sheet2」を指定して
'いるためと推測されます。
'他方、「Sheet2」がアクティブじゃない時に「"A1:F30"」のようなセル範囲を使った場合は、
'例えば「Worksheets("sheet2").Range("A1:F30").Sort・・・
'の先頭の「Worksheets("sheet2").」を省略するとエラーになります。
'Rangeプロパティでセル範囲(Rangeオブジェクト)を指定する場合、
'親オブジェクトを省略すると「Activesheet.」とみなす、
'という決まりになっているためです。(これはヘルプに書いてあります。)
'つまり、「Sheet2」を見に行かなくなってしまうからです。
‵なのに並べかえの基準列の指定では「Worksheets("sheet2").」があるのでそれでエラーになります。
例03:Worksheets("sheet2").Range("testtable").Sort ("abb"), xlAscending, Header:=xlYes
'同じく「Sheet2」がアクティブじゃなくても、「Sheet2」の「testtable」と名前定義したセル範囲を、
'「abb」という列名の列で昇順に。(列名除外)
(ロ)Sort オブジェクト、SortFieldオブジェクト(2007以降)
Webで「Sort オブジェクト」で検索してみてください。
https://excelwork.info/excel/cellsortcollection/ とか、
http://officetanaka.net/excel/vba/tips/tips148.htm
【検索】
Range.Find メソッド
例01:Debug.Print ActiveSheet.Range("A1:G100").Find("test").Address
'セル範囲「A1:G100」の中のtestという値のセルのアドレスを表示。
【DAOやADOのレコードセット丸ごとの一括シート貼り付け】
Range.CopyFromRecordsetメソッド
(ただし、張り付くのは実データだけで列名は一括貼り付けされないので、列名だけは別個に転記する必要があります。)
例:Range("A2").CopyFromRecordset rs
'A2セルを起点(左上隅)にして、「rs」というレコードセットのすべてのデータを一括貼り付け
【DAOやADO、Microsoft Queryで、ループ処理を使わずに、SQLで一括データ書き換え】
ExcelVBA直接、ということではないかもしれませんが、SQLを使うと、複雑な条件指定での「一括データ書き換え」を「FOR~NEXTやDo~Loop」などのループ処理を使うことなく、データの一括書き換えができます。
しかも、書き換えたいファイルが別のExcelファイルの場合、そのファイルが「閉じたまま」、読み込みだけでなく書き換えや追加削除もできてしまいます。
また、データの書き換え条件には列名や値を使い、セルアドレスは使わないので、プログラムの可読性がすごく上がります。ビジネス定型集計で表を扱うだけなら、その表をクラスモジュールでオブジェクト化したりする必要もありません。理由は、ADO、DAOなどにすでに備わっている「機能が満載のオブジェクト」が使えるためです。それ以上の機能のオブジェクトをクラスモジュールで自作するなら、相当の理由がない限り、使う場面がありません。
(SQL=データ管理の「世界標準の基礎」の機能・命令語句→ 参考記事『用語:「SQL」とは?』)
例:こちら ← の記事をご参考にしてください。「DAOやADOのオブジェクトとメソッド」、「MicrosoftQuery」での閉じたExcelファイルの書き換え、等々について書いてあります。
【表のデータ(セル範囲)を一括でコピー、別のシートにペースト】
基本、値も数式も書式も貼り付きます。また、「形式を選択して貼り付け」もできます。Rangeオブジェクトを使ってやるので、名前定義のされたセル範囲も同じ方法でやれるのではないかと思います。
また、前述の、UsedRangeやSelectionも使えます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
' ' Sub test02() 'シート1のA1を起点とした表範囲をコピー Worksheets("sheet1").Range("A1").CurrentRegion.Copy 'シート2へ、コピーしたセル範囲をA1を起点にペースト Worksheets("sheet2").Range("A1").PasteSpecial Paste:=xlPasteAll 'Worksheets("sheet2").Range("A1") の代わりに、 'ActiveCell.CurrentRegionや 'ActiveSheet.UsedRange、 'ActiveWindow.Selection、なども使えます。 '(但し、アクティブなシートやウィンドウ以外はエラーか動作不良になりますし、Sheet2のアクティブなセルの位置によって挙動が変わりますが。) End Sub ' ' |
【フィルタをかけた表の結果(セル範囲)を一括でコピーまたは削除】
コピーの場合は基本、値も数式も書式もコピーできます。以降のサンプルではやっていませんが、コピー後はもちろん、「形式を選択して貼り付け」もできます。
ただし、基本、バージョン2002以降(2002の一部?かも??)は、フィルタ機能自体の動き自体が治されていて、多くのケースで「何もせずとも」「そのまま」「絞りこんだ結果だけ」に、色々とできるようになっています。つまり、表示されていないセルはちゃんと「無視される」・・・ということです。
そのため、最後の行を指定したりすることもなく変数宣言も不要で、そのまま「処理コードオンリーでやれる」、ことも少なくないです。
(ただ、「何もせずとも」「そのまま」「絞りこんだ結果だけ」に、色々とできる・・・というのは「完全」ではないそうです。詳しくは、http://officetanaka.net/excel/vba/tips/tips155c.htmの「見えていない非表示のセルに影響を及ぼす操作がひとつだけあるのですが、」云々の箇所を。
ただ、その結果、「Range.CurrentRegion プロパティ」を記述するだけで、変数設定も最終行指定も両方とも不要で、「まんまで」「絞り込まれたあとの」セル範囲をも、取得できます。
例えば絞り込まれた行「だけ」をすべて削除したい場合は、たとえば、
「Activesheet.Range("A1").Currentregion.Offset(1,0).EntireRow.Delete」
とか、
「Activesheet.Range("A1").Currentregion.Offset(1,0).Resize(Activesheet.Range("A1").Currentregion.Offset(1,0).Rows.Count - 1).EntireRow.Delete」
などといった書くだけ、で済み、変数設定も最終行指定も両方とも不要で、削除できます。
で、繰り返しになりますが、バージョン2000以前(2002の一部もかも??)は、以上のことができません。
フィルタ機能の動きの仕様自体が治ってないからです。
その結果、「Range.CurrentRegion プロパティ」では、「絞り込まれたあとの」セル範囲までは取得できません。表示されていないセルも一緒に取得されてしまいます。
そのため、たとえば、「Range.SpecialCells メソッド」を使わないと削除等々はできません。以下のサンプルのように。
もちろん、変数設定も最終行指定も両方とも必要です。
ただ、逆に言うと、以下のサンプルは、2000以降の「全バージョン」で、対応できます。
全バージョンに対応する必要が無いのなら、「Range.SpecialCells メソッド」を使わない方法で良いと思います。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
' ' Sub FilerRecOpe01() Dim LngTblLastRowNum As Long 'セル範囲の最後の行を格納するための変数 Dim ObjFilterRange As Range 'セル範囲を代入するためのオブジェクト変数 'セル範囲の最後の行を変数に格納 LngTblLastRowNum = Cells(Rows.Count, 1).End(xlUp).Row + 1 '「内容」という、列名分の1行分を追加しておく '列の挿入や連番の生成(この部分だけ、多くは「マクロの記録」機能でやりました) Rows("1:1").Select Selection.Insert Shift:=xlDown, CopyOrigin:=xlFormatFromLeftOrAbove Range("A1").FormulaR1C1 = "内容" 'フィルタ範囲をオブジェクト変数に代入(コードが長くて見にくくなるので) Set ObjFilterRange = ActiveSheet.Range("$A$1:$A$" & LngTblLastRowNum) '2列目の、「MMV」で始まるセルを含む行をフィルタ ObjFilterRange.AutoFilter _ Field:=1, _ Criteria1:="MMV*" 'フィルター表示された行だけを削除、あるいはコピー。(2行目がコピー) '2000や2002ではこれを使うしかないようです。 ' Activesheet.Rows("2:" & LngTblLastRowNum).SpecialCells(xlCellTypeVisible).Delete Activesheet.Rows("2:" & LngTblLastRowNum).SpecialCells(xlCellTypeVisible).Copy ' 'すべて表示(「Criteria1:=」を省略すると全件表示になるとヘルプにありました。) ' ObjFilterRange.AutoFilter Field:=2 End Sub ' ' |
【Variant型の変数に、「配列として」表のデータを一括で代入し、別のシートに一括転記】
※ただし、コピー先のほうは「値の貼り付け」の状態と同じとなります。つまり、「セルそのもの」のオブジェクトとしてのコピーはされませんので、前述の【表のデータ(セル範囲)を一括でコピー、別のシートにペースト】のように、セル書式まで貼り付きはしません。)
詳しくは『シートにVariant型の配列データを一気に展開(出力)する』をご参照ください。以下、そこから引用
『 var = Worksheets(1).Cells(1, 1).CurrentRegion.Value 』 ←セルの値をVariant型の配列に代入
『 Cells(1, 1).Resize(UBound(var, 1), UBound(var, 2)).Value = var 』
↑代入されたものをシートに書き出し。
二次元配列を同じだけのセル範囲を用意しないと正常に貼り付かないので、
貼り付ける先のセル範囲をResizeやUBoundで設定しながら貼り付いています。
※上記の例は、Variant型の変数を使って配列として扱います。
「Set = ・・・」とやらないで、「変数 = Range(セル範囲)」と、普通の代入のようにやります。「Set」を使わないことで、指定したセル範囲のすべてのセルの「値」「のみ」が全部、Variant型の変数の中に、配列として代入されます。(セルの指定では、列名も含めます。)
「Variant型の配列」は、もちろん 1次元配列・2次元配列、いろいろ扱えますが、『 セル範囲をVariant型の配列に代入したときに限り 』ますと、内部的に・自動的に「2次元配列に変換され、そして、セルの「値」「だけ」が代入されます。
また、その代入されたものを別のシートや同じシートの離れた場所に貼り付ける(出力する)には、2次元配列と同じサイズ(同じ行の数と列の数)だけのセル範囲を指定して貼り付けないと正常に貼り付きません。1つのセルだけを指定して貼り付けようとすると、そのセルだけに値が入るだけに終わってしまいます。
なので、上記の例のように、貼り付ける先のセル範囲をResizeやUBoundで設定しながら貼り付ける必要があります。
(なお、あらかじめ配列の中の列と行の数が分かっていて、「A1:G10」などといった感じで、貼り付け先のセル範囲が特定できるようなら、『 Range("A1:G10") = Variant型の変数 』という指定をしてもOKです。表として正常に貼り付きます。” ResizeやUBoundを使わなくても。” )
以下は、「セル範囲の代入」の例です。
Dim v_RngVal01 As Variant
v_RngVal01 = Range("A1:C3")
v_RngVal01 = Range("名前の定義でつけた表の名前")
v_RngVal01 = Application.ActiveWindow.ActiveCell.CurrentRegion
v_RngVal01 = Application.ActiveSheet.UsedRange
v_RngVal01 = Application.ActiveWindow.Selection
v_RngVal01 = Application.Selection
Sheet2.Cells(1, 1).Resize(UBound(v_RngVal01, 1), UBound(v_RngVal01, 2)).Value = v_RngVal01
◆超重要な注意!!!!
あと、セルをVariant型の2次元配列に代入すると、For Each 文で各要素を(ループとして)回すときは、
下(行)方向が先で、そのあと右(列)方向に回ります。(列単位で回る)
しかし、配列に代入せず、そのままセル範囲を For Each 文で回すと、
右(列)方向が先で、そのあと下(行)方向に回ります。(行単位で回る)
ここは注意が必要です!!!!
※参考URL→https://www.relief.jp/docs/excel-vba-order-for-each-looping.html
また、配列のその縦横の並びを、「(新しいVariant型の変数を使って)・そのVariant型の変数の内部で」入れ替えるには、WorksheetFunction.Transpose を使うと良いようです。(以下の例をご参照ください。)
v_Rng01 = o_SrcWS.UsedRange '横方向に展開されたセルを代入した2次元配列を
v_Rng02 = WorksheetFunction.Transpose(v_Rng01) '縦方向の2次元配列に変換する
あるいは
新しい変数を用意しないなら、
v_Rng01 = o_SrcWS.UsedRange '横方向に展開されたセルを代入した2次元配列を
v_Rng01 = WorksheetFunction.Transpose(v_Rng01) '縦方向の2次元配列に変換する
(ちゃんと変換されたかをローカルウィンドウで確認したい場合は、前者のように変数を分けたほうがわかりやすいです。)
ついでですが、「WorksheetFunction.Transposeメソッド」は、「1列だけ・あるいは・1行だけ」の2次元配列であれば(それに限り??未チェックです)、「1次元配列」に一発変換することができます。
ただ、そのとき、
縦の1列分のセル範囲をVariant型の変数(自動的に2次元配列になる)に代入した時は、1回使えばいいですが、
横の1行のセル範囲を代入した時は、2回、使います。
なお、1次元配列になった瞬間に、縦のセル範囲のものが横になります。横のモノは横のままです。
(2次元配列は、縦にも横にもできます。)
(※後述のプログラム「test22()」もお試しください。どう操作したときに、どうセルに値が貼りつくのか、色々わかります。)
縦のセル範囲の場合で、「1つの変数だけでやる=変数を上書きする」ときの例
v_Rng = Worksheets("Sheet2").Range("A1:A3")
v_Rng = WorksheetFunction.Transpose(v_Rng)
ヨコのセル範囲の場合
v_Rng = Worksheets("Sheet2").Range("E1:G1")
v_Rng = WorksheetFunction.Transpose(v_Rng)
v_Rng = WorksheetFunction.Transpose(v_Rng)
ローカルウィンドウでF8のステップ実行で、変数の中身の変化を確認してみてください。
ただ、これを見ると、逆に言うと、「1列だけ」のセル範囲をVariant型の配列に代入した際は、いきなり1次元配列に変わってしまうので、「それが原因でエラー」になるケースもあるかもしれません。ちょっと注意が必要かもしれません。
Variant型に代入したときは、基本的には2次元配列になる。
R1C1形式みたいな感じ。
A1~A5に上から順番に「1、2、3、4、5」と入力したものを
variant型に代入すると以下のようなイメージで、配列に値が格納される。
Cells(1,1)=1
Cells(2,1)=2
Cells(3,1)=3
Cells(4,1)=4
Cells(5,1)=5
v_var01(1,1)=1
v_var01(2,1)=2
v_var01(3,1)=3
v_var01(4,1)=4
v_var01(5,1)=5
https://excel-ubara.com/excelvba5/EXCELVBA228.html の、
「2次元配列を1次元に変えて、シートに書き出す」という部分を、ちゃんと動きをチェックする必要があります。
前述とおり、1列のみの2次元配列を一発で、1次元配列に変換するには、 WorksheetFunction.Transposeメソッドを使います。(1行のみ、の場合は2回、WorksheetFunction.Transposeメソッド を使います。)
以下、プログラムでの利用例です。
「1列のみ」の2次元配列を変換している例です。(「1行のみ」、ではなく。)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 |
' 'A1:A3に、以下の値を入れておく 'めぐすり '頭痛薬 '風邪薬 Sub test22() Dim v_Rng As Variant Dim v_Rng02 As Variant Dim v_Rng03 As Variant ActiveSheet.Range("C1:G10").ClearContents v_Rng = Worksheets("Sheet1").Range("A1:A3") '縦のセル範囲が、縦の2次元配列に自動的に成る。 Stop v_Rng02 = WorksheetFunction.Transpose(v_Rng) '1次元配列に変換される→1次は自動的に「横」展開される。 Stop v_Rng03 = WorksheetFunction.Transpose(v_Rng02) '再度縦の2次元配列に戻る Range("C1:C3") = v_Rng02 '配列が1次元=横、だと、縦の範囲の指定の場合だと、最初の要素の値だけが縦に貼りついてしまう。 Range("E1:G1") = v_Rng02 '配列が1次元=横、だと、ヨコの範囲の指定の場合なら、うまいことヨコに貼りつく。 Range("E3:G3") = v_Rng03 '配列が2次元の縦の場合だと、ヨコの範囲の指定の場合だと、最初の要素の値だけがヨコに貼りついてしまう。 Range("E5:E7") = v_Rng03 '配列が2次元の縦の場合だと、うまいこと縦に貼りつく。 End Sub '======================= Sub test() Dim v_Rng As Variant '2次元配列用 Dim v_Rng02 As Variant '1次元配列用 v_Rng = Worksheets("Sheet1").Range("A1:A3") '基本、Variant型の変数は、「配列を代入する」こともできます。 'で、Rangeオブジェクト(セルの集合体≒セル範囲)を代入すると、 'Variant型の変数は、自動的に内部的に '「2次元配列として(=表として)」の「配列変数」に変身し、 'そのセルの集合体(=セル範囲)の「値」を、 '「表として」一発でゲットできます。 'だたここでは、のちのちの、「Range.AutoFilter」メソッドでは、 '一次元配列じゃないと3つ以上の条件(語句)でのフィルタがかけられないので '次の1行で、「Variant型の2次元配列」から「Variant型の1次元配列」に '一発変換します。 '「Worksheets("Sheet1").Range("A2:A:4")」 の部分は、 'Activecell.CurrentRegionや、ActiveSheet.UsedRnge、 'Worksheets("Sheet1").Range("名前定義をしたセル範囲の名前") 'なども使えます。 'また、条件のセル範囲の中の一部のセルが空白でも一応は大丈夫っぽいです。 'もちろん、別のシートのセル範囲でもOKですし、 '同一シートに、条件専用のセルを確保し、それを対象にしてもOKです。 'あと、条件のセルは、表と別じゃなくても、 '表そのものの中のセルでもOKです。 v_Rng02 = WorksheetFunction.Transpose(v_Rng) 'Variant型の配列は2次元配列なので、 'WorksheetFunction.Transpose 関数?にて、1次元配列に変換します。 'https://thom.hateblo.jp/entry/2018/08/02/073503 'を参照してください。 '縦のセル範囲だけでなく、横のセル範囲も変換できるようです Worksheets("Sheet1").Range("C1:E10").AutoFilter Field:=1, Criteria1:=v_Rng02, Operator:=xlFilterValues '3つ以上の語句でフィルタの実行。 'バージョン2007?以降の「Range.AutoFilter」メソッドは、 'Criteria1:= に一次元配列 'Operator:= に「xlFilterValues」を指定すると、 '配列の全部の語句で、「完全一致でのOr抽出」をしてくれるそうです。 '一番最初の「v_Rng = Worksheets("Sheet1").Range("A2:A4")」にて、 'セル範囲を広げれば、4つ、5つ、と End Sub ' ' |
【Variant型の変数に、「配列として」表のデータを一括で代入し、ループの高速化テスト】
セルに対するループ処理はVariant型変数と配列とCellsプロパティを組み合わせることが一番高速だそうです。
For Each文やRangeを使ったループでは全セルを逐一参照してしまうけど、配列とCellsプロパティを組み合わせたループなら、ループの前(最初)とあと(最後)の2回だけしかセルを参照しないからだそうです。
セル範囲を一括で読み込んで、一括で貼り付けるために、Variant型の変数を使っています。セルの値をオブジェクト型として・配列として読み込んでも、各要素へ数値を上書きすることによって自動的に、各要素は数値系のデータ型になるようです。(ローカルウィンドウで確認できます。)
▼ 速度比較決定版【Range,Cells,Do,For,ForEach】
▼ VBA・Excel 高速化したい!遅い、重いを配列で一気に解決!
▼ VBA・Excel マクロを簡単に高速化する4つの方法!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
' ' Sub FastOutput() '配列を使った速いコードです。 'With Application ' .ScreenUpdating = False ' .EnableEvents = False ' .DisplayStatusBar = False ' .Calculation = xlCalculationManual 'End With Dim my_array As Variant Dim i As Long Dim j As Long my_array = Range("A1:ALL1000") For i = 1 To UBound(my_array) '縦のループ For j = 1 To UBound(my_array, 2) '横のループ my_array(i, j) = Int(Rnd(10) * 1000) Next Next Range("A1:ALL1000") = my_array End Sub ' ' |
【配列を利用してのレコードの追加(テーブルや、非テーブル)】
★★★★★★Access2000VBA・Excel2000VBA独学~、新規レコードの一括セルデータ(レコード)追加のプログラム。(テーブル化した表の場合と、そうじゃない表の場合)~
【帳票データを一括で一覧表に変換】
★★★★★★Access2000VBA・Excel2000VBA独学~例えば、セル結合もある、「3行単位で1レコード」の帳票を、1行1レコードの一覧表に変換する若干汎用的なプログラム~
(52-2)リスト表への新規レコードの追加など(セルの最終行の取得とOffsetプロパティ)
DAOかADOかQueryTableオブジェクトとSQLを知っていれば、INSERT、あるいは、AddNewなどをするだけなのですが、Rangeオブジェクトとして新規レコードの追加をしたい場合は「Range.End プロパティ」などを使って最終行の位置を求めつつ、その次行に新規レコードを追加します。(というか、1セルずつ順番に埋めていく感じ。)
最終行を取得する例:イミディエイトウィンドウにて、A列の最終行(最終セル)のアドレスを求める例
? Cells(Rows.Count, 1).End(xlUp).Address
? Cells(Rows.Count, "A").End(xlUp).Address
入力されているデータの最終セルを取得する(Offsetプロパティの詳しい解説も)
もしかしたら、Variant型での配列データを、一括貼り付けしてもOKかもしれません。
(53-1)単位セルごとの一括処理には基本、「For Each ~ Next文」や一括処理専用のメソッドなどを使い、カウンタ変数を用いたループ処理は特殊な場合のみ使う、ということのほうが良いかも?
◆超重要な注意!!!!
セルをVariant型の2次元配列に代入すると、For Each 文で各要素を(ループとして)回すときは、
下(行、縦)方向が先で、そのあと右(列、横)方向に回ります。(列単位で回る)
しかし、配列に代入せず、そのままセル範囲を For Each 文で回すと、
右(列、横)方向が先で、そのあと下(行、縦)方向に回ります。(行単位で回る)
ここは注意が必要です!!!!
※参考URL→https://www.relief.jp/docs/excel-vba-order-for-each-looping.html
また、配列のその縦横の並びを、「(新しいVariant型の変数を使って)・そのVariant型の変数の内部で」入れ替えるには、WorksheetFunction.Transpose を使うと良いようです。(以下の例をご参照ください。)
v_Rng01 = o_SrcWS.UsedRange '横方向に展開されたセルを代入した2次元配列を
v_Rng02 = WorksheetFunction.Transpose(v_Rng01) '縦方向の2次元配列に変換する
あるいは
新しい変数を用意しないなら、
v_Rng01 = o_SrcWS.UsedRange '横方向に展開されたセルを代入した2次元配列を
v_Rng01 = WorksheetFunction.Transpose(v_Rng01) '縦方向の2次元配列に変換する
(ちゃんと変換されたかをローカルウィンドウで確認したい場合は、前者のように変数を分けたほうがわかりやすいです。)
ついでですが、「WorksheetFunction.Transposeメソッド」は、「1列だけ・あるいは・1行だけ」の2次元配列であれば(それに限り??未チェックです)、「1次元配列」に一発変換することができます。
ただ、そのとき、
縦の1列分のセル範囲をVariant型の変数(自動的に2次元配列になる)に代入した時は、1回使えばいいですが、
横の1行のセル範囲を代入した時は、2回、使います。
なお、1次元配列になった瞬間に、縦のセル範囲のものが横になります。横のモノは横のままです。
(2次元配列は、縦にも横にもできます。)
(※前述のプログラム「test22()」もお試しください。どう操作したときに、どうセルに値が貼りつくのか、色々わかります。)
縦のセル範囲の場合で、「1つの変数だけでやる=変数を上書きする」ときの例
v_Rng = Worksheets("Sheet2").Range("A1:A3")
v_Rng = WorksheetFunction.Transpose(v_Rng)
ヨコのセル範囲の場合
v_Rng = Worksheets("Sheet2").Range("E1:G1")
v_Rng = WorksheetFunction.Transpose(v_Rng)
v_Rng = WorksheetFunction.Transpose(v_Rng)
ローカルウィンドウでF8のステップ実行で、変数の中身の変化を確認してみてください。
ただ、これを見ると、逆に言うと、「1列だけ」のセル範囲をVariant型の配列に代入した際は、いきなり1次元配列に変わってしまうので、「それが原因でエラー」になるケースもあるかもしれません。ちょっと注意が必要かもしれません。
(54-1)NameプロパティとCodeNameプロパティの違い
(55-1)目的のオブジェクトのインデックス番号がわからないときのあたりの付け方
=====================================
(56-1)★ ヒント:「部分オブジェクトの取得」の基本は、まずは3パターンくらいから。
=====================================
(57-1)今選択されているオブジェクトの、「階層構造を省略しないオブジェクト式」の作り方・書き方
(a)使うもの
・「選択したオブジェクトの調査シート白地.xls」(当方自作の参考ツール)
・ヘルプ(主に、オブジェクトを特定するための構文を。)
・オブジェクトブラウザ
(いろいろ。オブジェクトの上下の階層構造や下位オブジェクトのことなどを。)
・VBE(Visual Basic Editor)のイミディエイトウィンドウ
・Stop命令とVBEのローカルウィンドウ
(主にプロパティの値やオブジェクトの上下の階層構造、列挙の設定値などを。)
・3つの自作関数(→こちらの3つ)
・「TypeName関数」と「Parentプロパティ」
・その他の関数、ほか
(b)「オブジェクト式」とは?:「オブジェクト式」と「部分オブジェクト式」
(c)大まかな流れ(概要・ポイントのみ。何を使うかなど。)
(03)のオブジェクト式を書くための道具たち(重要度順)
「選択したオブジェクトの調査シート白地.xlsx」(当方自作の参考ツール)
(d)イミディエイトウィンドウで使う自作関数(ちょっとした省力化)
・すべての上位のオブジェクト名を一覧表示(「Obchk03Type」という自作関数)
・すべての上位のオブジェクトの名前を一覧表示(「Obchk04Name」という自作関数)
・すべての上位のオブジェクトのインデックス番号を一覧表示
(「Obchk05Index」という自作関数)
・色の数値を「赤・緑・青」の数値に変換する(「GetIntByRGB」という自作関数)
(e)実例01:グラフシートのオブジェクト01~棒グラフの「目盛線」~
(f)実例02:グラフシートのオブジェクト02~棒グラフの「縦の数値軸(X軸)」~
(g)実例03:ワークシートの埋込グラフのオブジェクト01~棒グラフの「棒グラフの「系列」の1つ」~
(h)実例04:ワークシートの埋込グラフのオブジェクト02~棒グラフの「棒グラフの棒の1つ」~
=====================================
「Item」で検索すると「コレクション(=コレクションオブジェクト)」のみが絞り込み表示されます。
そこにないものはコレクションではありません。
=====================================
(59-1)ヘルプの読み方(ヘルプ用語:その他)
(a)2000系のヘルプと2007系のヘルプの違い(どちらも優秀なのでできれば両方欲しいです)
『Access2000VBA・Excel2000VBA独学~XPやWin2000、あるいはその仮想マシンの中で、Office2000~2003でADOやDAOのヘルプをきちんと表示する方法と、2000系のヘルプと2007系のヘルプの違い・良さ。』
(b)ヘルプおきまりの言い回しなどについて
(c)プログラミング用語とヘルプ
=====================================
(07)オブジェクトブラウザの使い方
(a)オブジェクトブラウザで今のオブジェクトの下位のオブジェクトやプロパティを探し、何が使えるかを調べる
(b)同時にヘルプのメンバーの一覧でも調べる(2010での見方、Web検索の仕方)
(c)F1でのヘルプとの連携
=====================================
(59-2)「マクロの自動記録」でオブジェクト式の書き方について学ぶ
(59-3)ヘルプでオブジェクト式、部分オブジェクト式の書き方について学ぶ
(60-1)ローカルウィンドウの使い方
(a)Stop関数との併用で瞬間瞬間?のオブジェクトのプロパティの値を調べる
=====================================
(61-1)「VBE(VisualBasic Editor)」の操作の基礎
(a)最小限の基礎
(b)その他の使い方
=====================================
(62-1) 「API」について
=====================================
(63-1) 「SQL」について
=====================================
(64-1) 「ADO・DAO(ミドルウェア)」について
・『 DAOやADOで、閉じたExcelファイルを、閉じたまま、「読み書き」することについて 』
https://euc-access-excel-db.com/00000WPhtml/dao_ado_close_file_read_write01.htm
A4印刷用(↓Ctrl++やCtrl+- 等々にて、拡大縮小ができます。)
https://euc-access-excel-db.com/00000WPPDF/dao_ado_close_file_read_write01.pdf
(64-2)Range.CopyFromRecordsetメソッドで、DAOやADOレコードセット(表データ)をループを使用せずにExcelシートに一括貼り付け
(65-1)「For Each ~ Next文」で、DAOやADOレコードセット(表データ)の列や行を一括処理
(「For Each ~ Next文」はDAOやADOレコードセットのオブジェクトにも使えます。「すべての列」とか。)
(65-2)DAOやADOで表をレコードセット化(ある意味にオブジェクト化)することは、クラスモジュールを使って表をオブジェクト化するよりも、30~100倍は便利で効率がいい。
(65-2)DAOやADOはExcelだけでなく、Word、Access、PowePoint、Outlookなどでも使えるし、Web系のプログラム(PHPやASPなど)でも使えます。
(66-1)オブジェクト式を書くための道具たち(重要度順)
(a)オブジェクトモデルの階層構図の全体図(オブジェクト所得・操作の羅針盤。最重要なツール。)
2000のものしかないけど役に立ちます。
この2000のヘルプの全体図は、ちょっと形が変わりますが、Webにもあります。
MSサイト→こちら /少し見やすく横につなげたもの→こちら /Excel2000の色付きの見やすいものを全部つなげたもの→こちら
参考記事
『Access2000VBA・Excel2000VBA独学~XPやWin2000、あるいはその仮想マシンの中で、Office2000~2003でADOやDAOのヘルプをきちんと表示する方法と、2000系のヘルプと2007系の「”VBE”ヘルプ」の違い・良さ。』
(c)VBE(Visual Basic Editor)の「オブジェクトブラウザ」
(d)VBEの「イミディエイトウィンドウ」
(e)「選択したオブジェクトの調査シート白地.xls」(当方自作の参考ツール)
(f)「TypeName関数」と「Parentプロパティ」と、VBEのイミディエイトウィンドウ
(g)「Stop」命令又は「ブレークポイント」と、VBEのローカルウィンドウで
(g-2)「TypeName関数」「Parentプロパティ」「Stop」命令を使った、「上位のオブジェクト階層構造を知る・取得する」ための自作関数
Access2000VBA・Excel2000VBA独学~「選択したオブジェクトの調査シート白地.xls」(当方自作の参考ツール)~3つの自作関数とともに。★ ~Current無省略オブジェクト式記述~
(h)Web情報・Web記事
(i)マクロの自動機能で自動作成されたコード(特に列挙体・列挙・定数を調べたいときに)
例えば、ワークシートに埋め込んだグラフの縦軸の色を赤に変える作業をマクロの記録機能で記録。
Sub test01()
' test01 Macro
'
ActiveSheet.ChartObjects("グラフ 1").Activate
ActiveChart.Axes(xlValue).Select
'「線のスタイル」タブ?の設定
With Selection.Format.Line
.Visible = msoTrue
.Weight = 3.5
End With
'「線の色」タブ?の設定
With Selection.Format.Line
.Visible = msoTrue
.ForeColor.RGB = RGB(255, 0, 0)
.Transparency = 0
End With
End Sub
=====================================