★独学者が1年後にExcelVBAを爆発的に伸ばすための最低限の基礎知識メモ(ダイジェスト):Vol0010:「Variant型」の変数の使いどころ
バックナンバー目次ページは→こちらです。
まぐまぐのページは以下です。
https://www.mag2.com/m/0001691660.html
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
■独学者が1年後にExcelVBAを爆発的に上達させるための最低限の基礎知識メモ(ダイジェスト)
Vol.0010
タイトル:「Variant型」の変数の使いどころ
バックナンバー目次とサンプル号
https://euc-access-excel-db.com/tips/ct07_se/ct075012_xls2k_vba_tips/mag2-01
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
(b)Variant型の配列変数として、セル範囲の値を一発で表データ(=2次元配列)としてゲットし、それを別にシートに一発で貼り付け
(c)Variant型の配列変数としてや、For Each 文を利用して、など
(d)1行のみ、あるいは、1列のみ、の2次元配列を一発で(1行コードで)1次元配列に変換する。
(e)2列×2行以上の2次元配列の縦ヨコを、一発で(1行コードで)入れ替える。
(g)オブジェクト型の変数の、より明確な型を調べる手段として
(i)関数やメソッド、プロパティから返ってくる値がよくわからない時(オブジェクトブラウザがまだ使える能力がないとき)の、返ってくる値の型の調査
(j)値やオブジェクトを返す自作関数で、返すモノを「複数」返したいときに使えます。
※Shift+TABキー、を押すと、目次付近に戻れます。
今回は「かなり」批判的な内容が多いのでどうかお許しください。
気持ちのよいものではないと思いますので、ご気分を害されたくない方は読まないほうがいいかもしれません。
本当に申し訳ありません。
でも「なぜExcelVBAの独学者の多くは上達できないのか?」「挫折してしまうのか?」
に、大きく関係することなので、もし批判が我慢できるようでしたら、もし、よろしければ読んでみてください。
では以降、進めさせていただきます。
今回は『「Variant型」の変数の使いどころ 』についてです。
「Variant型」の変数については・・・、
まず、「変数の型は全部Variant型でいい」という使い方は「もっとも最低で愚か」な使い方です。
最近そう書いてある書籍やWebサイトが増えてきましたが、絶対にしないようにご注意ください。
理由は、
そんな使い方ばかりしていると、
「VBAの真のスタートラインの、値やオブジェクトを返す自作関数(汎用部品)の作成が一生できなくさせられ」、
「それが一生できないので、スタートラインにすら立てなくさせられ」
「VBA的にはバカになる一方」
「VBA的にはバカにさせられる一方」
だからです。
なので、ぶっちゃけ、「変数の型は全部Variant型でいい」という愚かな考え方の人には、教わらないほうが無難です。
もちろん、その人の書いた書籍やサイトの中で、そう書いてある以外の場所で参考になる記述があれば、もちろん参考にすればいいと思いますが、
ただ、そういう考え方の人は、基本的に・・・
「初心者をカモろうとしているだけで、育てようなんてこれっぽっちも考えてない」、
「そう意図してなくても、結局自分のいいかげんな教え方のせいで挫折者を増やすだけ、結局カモッている、ということが、” まったく自覚できてない ” 」、
ということが明白です。
そんなのが「基本スタンス」なので、多分(当然)、他の箇所でも
「いいかげんなことを書いても平気」、
「学習者を成長をさせない書き方をしても平気」、
という書き方をちょいちょいしているはずなので、そういう人の情報には慎重に接したほうがいいと思います。
少なくとも
「どうしたらヘルプとオブジェクトブラウザが、初心者の人にでも読みやすくなるか?」
なんてことは、「1ミクロンも」考えていません。
もし「微塵」でも考えていたら、彼らが書くような、そんな書籍やWebサイトの内容には、
「絶対になるわけがない」
です。
とは言うモノの、エラそうなこと言ってばかりですみませんが、僕自身もかなりいいかげんなことを書いていると思うので、自分で言うのもいけないとは思いますが、でもやっぱり充分に慎重に接してください。(間違って理解してる部分もあろうかと思いますので)
ただ、僕自身、学ぶ側として、「市販書籍では、まともな著者に出会ったことが、基本、無い・・・」と良く思います。あっても1、2冊、程度です。
新しい初心者本が出るとおおむね立ち読みで中身をざっと見ますが、過去に、
「これは誰かに教えるのに使える」、
と思った本は本当に1、2冊程度です。
それ以外はすべて、マンガのVBA初心者本のほうがよっぽどかマシです。
(あと、Excel2000以前の本のほうがかなりまともです。)
なんで、Excelが出て20年以上も経つのに、それが「変わってない」のでしょう?
不思議で仕方がありません。
どんどん表面的で省略だらけの、「度を越して」、浅「過ぎる」教え方になっています。
特に本メルマガでお伝えしていることに関しては・・・。
ひどいありさまです。
その最たるもの・・・・、
象徴的な最低の教え方・・・・、
それが「変数の型は全部Variant型でいい」という教え方です。
「Withしか説明してなくてオブジェクト変数の良さをまったく説明しない」本やサイト、
「変数の型は全部Variant型でいいという説明しかしない」本やサイト、は、
「VBAの基礎・スタートライン目線」としては、
「最低の部類」に入りますので
基本、その「著者・筆者のことは」「信用しない」ほうがいいです。
書籍やサイトの内容はともかく。
もちろん参考になるページは参考にすればいいですが、
でも、
「騙されないように」
「慎重に接する」
ことが重要です。
本当に、騙されないように、ご注意下さい。
「教科書」を名乗る本ほど、「たくさん色んな事例を載せたいので」、「よくやる操作だけ」の、うわっつらだけの、表面的でいいかげん、な、
「応用がほとんど利かない絆創膏テクニックなだけ」という内容、
になる傾向が強い気がします。
どうやら「売れてる部数が正義」ということのようなんですが・・・。
そもそも、「Variant型」の変数は、そんな腐った使い方以外に、以降の(a)~(j)に挙げたような便利な使い方があります。(特にループを使わずに色んな処理ができたりして便利です。)
Variant型以外の型についてしっかり学んで、以降の(a)~(j)のような方法も活用・併用すると、上達が早まります。
これらのほかにも、まだたくさんあると思いますので、ご自分でも調べてみてください。
僕のようなExcelVBA初心者の人間でも、これくらいのことはパッと思い出せるので、他の方ならもっと見つかると思います。
(b)Variant型の配列変数として、セル範囲の値を一発で表データ(=2次元配列)としてゲットし、それを別にシートに一発で貼り付け
(c)Variant型の配列変数としてや、For Each 文を利用して、など
(d)1行のみ、あるいは、1列のみ、の2次元配列を一発で(1行コードで)1次元配列に変換する。
(e)2列×2行以上の2次元配列の縦ヨコを、一発で(1行コードで)入れ替える。
(g)オブジェクト型の変数の、より明確な型を調べる手段として
(i)関数やメソッド、プロパティから返ってくる値がよくわからない時(オブジェクトブラウザがまだ使える能力がないとき)の、返ってくる値の型の調査
(j)値やオブジェクトを返す自作関数で、返すモノを「複数」返したいときに使えます。
※Shift+TABキー、を押すと、目次付近に戻れます。
それぞれ少し補足します。
(a)一括処理をする手段として
「For Each 文」などを使って、一括処理ができますし、次項の(b)のようなこともできます。
String型やLong型等々の配列において、要素の値を受ける(代入する)変数をVariant型にすると、「For Each 文」が使えます。
(b)Variant型の配列変数として、セル範囲の値を一発で表データ(=2次元配列)としてゲットし、それを別にシートに一発で貼り付け
「セル範囲」のValueをVariant型の変数に(Setを使わずに)代入すると、一発でそのセル範囲の値を、表のかたち=2次元のかたち、で、
Variant型の変数に格納することができます。
(「値のみ」で数式は代入できませんが。で、そのとき、自動的に・かつ・内部的に、2次元配列の変数に変換されます。)
ループ処理などで転記せずにすみます。
なお、2次元配列の場合、添え字をカウンタ変数で代用すると「配列の中だけで」縦のループ、横のループが使えます。これは、(f)との相性がいいです。
あるいは、(ループは関係無く)、単純に(d)や(e)との併用もできます。
(c)Variant型の配列変数としてや、For Each 文を利用して、など
For Each 文は、オブジェクトに対してと配列に対してのみ、使うことができます。
ただし、配列の場合は、配列の各要素を受ける変数がVariant型でなければなりません。
(配列自体の型はStringでもLongでも、VariantでもOKです。)
また、For Eachとは関係ありませんが、Variant型は、そのまま配列変数としても値を代入できます。
(d)1行のみ、あるいは、1列のみ、の2次元配列を一発で(1行コードで)1次元配列に変換する。
(入れ替え後も配列の形は維持されます。配列の中で1次元化の変換がなされます。)
ループ処理などで変換せずに済みますのでコードがすごく少なくなって大変便利です。
これは、(b)との併用もできます。
以下、例です。
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 |
' ' Sub test02() Dim var As Variant var = Worksheets("Sheet3").UsedRange '1行のみ、あるいは、1列のみの、UsedRangeを、Variant型の変数に代入。 Worksheets("Sheet4").Cells.ClearContents var = WorksheetFunction.Transpose(var) '1行のみの2次元配列の場合は、この時点ではまだ縦ヨコを一発入れ替えで終わる。 '1列のみの2次元配列の場合は、この段階で、1次元配列に一発変換される。 'もともと、1行のみのセルデータと、1列のみのセルデータの場合は、処理の段階が異なる。 ' var = WorksheetFunction.Transpose(var) '1行のみの2次元配列の場合は、この行が要る。縦ヨコを入れ替えた2次元配列を1次元配列に変換 Worksheets("Sheet4").Cells(1, 1).Resize(UBound(var, 1), UBound(var, 2)).Value = var '値を貼り付ける先のRangeオブジェクトの列数と行数のサイズも入れ替えて、貼り付け。 'ただし、1次元配列に変換されてしまった「var」を貼り付けようとすると、エラーになる。 'もともとセルへは「2次元配列じゃないと貼り付けられない」ので。 End Sub ' ' |
(e)2列×2行以上の2次元配列の縦ヨコを、一発で(1行コードで)入れ替える。
(入れ替え後も配列の形は維持されます。配列の中でタテヨコ入れ替がなされます。)
これも、ループ処理などで変換せずに済みますのでコードがすごく少なくなって大変便利です。
そしてこれも、(b)との併用ができます。
以下、例です。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
' ' Sub test() Dim var As Variant var = Worksheets("Sheet1").UsedRange '2列×2行以上、の、セル範囲をVariant型の変数に代入。 Worksheets("Sheet2").Cells.ClearContents var = WorksheetFunction.Transpose(var) '2行3列の2次元配列の縦ヨコを一発入れ替え Worksheets("Sheet2").Cells(1, 1).Resize(UBound(var, 1), UBound(var, 2)).Value = var '値を貼り付ける先のRangeオブジェクトの列数と行数のサイズも入れ替えて、貼り付け。 End Sub ' ' |
(f)配列を利用しての高速処理用の変数として使える。
(セル単体だけで処理する場合の5~10倍以上の高速性を実現)
「セル直接への操作をループ処理することで動作速度が遅くなる」というときに、セルの値をいったんVariant型の配列に代入して、
そして先に配列のなかでいろんな処理をほどこし、
それらの処理が終わった段階でセルに結果を書き込む(戻す、などの)・・・という形にするとセルだけで完結するよりも・、体感速度で・5~10倍以上、高速に処理できます。
これは、(d)や(e)との併用もできます。
(g)オブジェクト型の変数の、より明確な型を調べる手段として
「Object」という型と同じ効能ですが、オブジェクト変数の型を、どう指定してよいかわからないときに、
「Dim ××× AS Variant」と、汎用的な変数宣言をすることで、ひとまずプログラムを進行させることができます。
(変数の型の宣言が間違ってのエラー、を回避できます。)
ローカルウィンドウとステップ実行(F8キー実行)で、具体的にどんな型に内部的に変換されるかもわかります。
「Object」型の型を使っても同じようなことができますが、「Object」の型の場合はオブジェクト変数に対してしかそのような調査ができませんが、
「Variant」なら、数値やその他の、「一般変数」の型についても、そのような調査ができます。
(ただし一般変数の場合は「あくまでも参考」であって「絶対」ではありません。特に数値系の形は信じすぎるとハマりますから注意が必要です。)
(h)Nullエラー回避の手段として(特にAccess)
Variant型は「Null」という特殊な値を代入することができます。
StringやLongなどには、Nullは代入できません。エラーになります。
特にAccessでは、Nullを多く使うので、
(i)関数やメソッド、プロパティから返ってくる値がよくわからない時(オブジェクトブラウザがまだ使える能力がないとき)の、返ってくる値の型の調査
(j)値やオブジェクトを返す自作関数で、返すモノを「複数」返したいときに使えます。
「・・・ピボットテーブルのワンクリック自動作成 ~ ・・・・」
https://euc-access-excel-db.com/tips/ct08_exceltruebasic/ct080860_vba_basic/auto-make-pivot01
の、ラストの追記のプログラムや、
「vba 複数の値を返す関数」のGoogle検索。
https://www.google.co.jp/search?sourceid=navclient&hl=ja&ie=UTF-8&rlz=1T4GGHP_jaJP820JP821&q=vba+%e8%a4%87%e6%95%b0%e3%81%ae%e5%80%a4%e3%82%92%e8%bf%94%e3%81%99%e9%96%a2%e6%95%b0#spf=1592720769387
などをご参考にしてみてください。
==============================
今回は以上です。
==========================================================================
バックナンバー目次とサンプル号
https://euc-access-excel-db.com/tips/ct07_se/ct075012_xls2k_vba_tips/mag2-01
----------------------------------------------------------------------
■独学者が1年後にExcelVBAを爆発的に上達させるための最低限の基礎知識メモ(ダイジェスト)
発行システム:『まぐまぐ!』 http://www.mag2.com/
配信中止はこちら https://www.mag2.com/m/0001691660.html
----------------------------------------------------------------------