- ホーム
- 講座一覧
- 講座「エクセルマクロ・VBA発展編2」
- 教材「Functionプロシージャ演習中」
Functionプロシージャ演習中
解説
この教材についての過去の質問・感想
12856 : 小川慶一の回答 (2021-01-21 13:19:23)
マメコトさん:
> ファンクションプロシージャを上手に使いこなせれば、以前はグローバル変数として宣言していたものをかなり減らせるのではないかと思いました。
> 「どのような処理をどの順番で行うか」
> を考えることで、その共通的な処理をファンクション化出来ると思いました。
まさに、です。
グローバル変数が不要になるのは大きなメリットですね。
その分、使いまわしの効く部品になります。
12854 : マメコトさんのコメント (2021-01-21 12:46:25)
ファンクションプロシージャを上手に使いこなせれば、以前はグローバル変数として宣言していたものをかなり減らせるのではないかと思いました。
「どのような処理をどの順番で行うか」
を考えることで、その共通的な処理をファンクション化出来ると思いました。
12251 : 小川慶一の回答 (2020-07-05 16:41:41)
受講生 さん:
こんにちは。
解決したようで良かったです (^^
LongLong型は、正直、僕も今回調べてはじめてその存在を知りました。
おそらく64bitマシンではLongLong型がInteger型、Long型より高速だろうなという気はします。が、整数を扱うデータ型がたくさんあっても戸惑いますし、整数については、エクセル作業であれば行番号すべてに対応できるものがあれば十分かなと思います。
僕ならDouble型を使いたいです。
ひきつづきよろしくお願いいたします。
12250 : 受講生さんのコメント (2020-07-04 16:57:56)
小川様
ご返信ありがとうございます。
> 2進数の b11000000101010000000000100000000 は、10進数に直すと 3,232,235,776 です。
⇒一桁少なり見間違えており、長整数型の範囲内と思ってしまいました。
仰る通り、オーバーフローするのは想定通りだと認識致しました。
また、double型に変更し、試した結果、期待値の動作となりました。
長整数型で扱えない数値はdouble型やlonglong型で対応する点が勉強になりました。
ありがとうございました。
小川慶一さん:
> kurosukeさん:
>
> 追記です。
>
> 2進数の b11000000101010000000000100000000 は、10進数に直すと 3,232,235,776 です。
> 一方、長整数型の取りうる最大値は 2,147,483,647 です。なのでオーバーフローになってしまうのは仕方ないですね。
> https://docs.microsoft.com/ja-jp/office/vba/language/reference/user-interface-help/data-type-summary
>
> Long型でも扱えない数値は、Double型に格納します。最近だとLongLong型等の型もあるようですので、これを使ってもOKです。
> 以下に、 double型、longlong型、long型で同じ処理を書いた場合のサンプルを示します。関数として切り出すところはご自身でやってください。
>
>
Sub check_overflow_limit() > Dim strByte As String, nagasa As String, i As Long, s As String > strByte = "11000000101010000000000100000000" > nagasa = Len(strByte) > > '[1] > Dim ret_double As Double 'どんな環境でもOK > For i = 1 To Len(strByte) > s = Mid(strByte, i, 1) > If s = "1" Then > ret_double = ret_double + 2 ^ (nagasa - i) > End If > Next > Debug.Print ret_double > > '[2] 64ビット環境ではこの型を使える > Dim ret_longlong As LongLong 'どんな環境でもOK > For i = 1 To Len(strByte) > s = Mid(strByte, i, 1) > If s = "1" Then > ret_longlong = ret_longlong + 2 ^ (nagasa - i) > End If > Next > Debug.Print ret_longlong > > '[3] オーバーフローする > Dim ret_long As Long > For i = 1 To Len(strByte) > s = Mid(strByte, i, 1) > If s = "1" Then > ret_long = ret_long + 2 ^ (nagasa - i) > End If > Next > Debug.Print ret_long > End Sub
>
12241 : 小川慶一の回答 (2020-07-02 08:06:11)
kurosukeさん:
追記です。
2進数の b11000000101010000000000100000000 は、10進数に直すと 3,232,235,776 です。
一方、長整数型の取りうる最大値は 2,147,483,647 です。なのでオーバーフローになってしまうのは仕方ないですね。
https://docs.microsoft.com/ja-jp/office/vba/language/reference/user-interface-help/data-type-summary
Long型でも扱えない数値は、Double型に格納します。最近だとLongLong型等の型もあるようですので、これを使ってもOKです。
以下に、 double型、longlong型、long型で同じ処理を書いた場合のサンプルを示します。関数として切り出すところはご自身でやってください。
Sub check_overflow_limit() Dim strByte As String, nagasa As String, i As Long, s As String strByte = "11000000101010000000000100000000" nagasa = Len(strByte) '[1] Dim ret_double As Double 'どんな環境でもOK For i = 1 To Len(strByte) s = Mid(strByte, i, 1) If s = "1" Then ret_double = ret_double + 2 ^ (nagasa - i) End If Next Debug.Print ret_double '[2] 64ビット環境ではこの型を使える Dim ret_longlong As LongLong 'どんな環境でもOK For i = 1 To Len(strByte) s = Mid(strByte, i, 1) If s = "1" Then ret_longlong = ret_longlong + 2 ^ (nagasa - i) End If Next Debug.Print ret_longlong '[3] オーバーフローする Dim ret_long As Long For i = 1 To Len(strByte) s = Mid(strByte, i, 1) If s = "1" Then ret_long = ret_long + 2 ^ (nagasa - i) End If Next Debug.Print ret_long End Sub
12240 : 小川慶一の回答 (2020-07-02 07:31:38)
kurosukeさん:
おはようございます。
> オーバーフローの解消方法をご教授頂けないでしょうか
という以前に、いろいろ問題がありますので、この関数を呼び出すプロシージャを含めた全体を紹介していただけますか。
というのは、この関数は文字列を受け取るとしていますが、
> 引数Valueには「11000000101010000000000100000000」が渡される想定です。
ということなので、実際には長整数型の値を関数に渡そうとしているように見えるからです。
実際にやってみるとわかりますが、
たとえば、
Sub CallTheFunc() Dim mystr As String Dim fuga As Long fuga=11000000101010000000000100000000 End Sub
等と書こうとしても、以下のように表示されてしまいます。
Sub CallTheFunc() Dim mystr As String Dim fuga As Long fuga = 1.100000010101E+31 End Sub
あと、以下のように書いてCallTheFuncを実行しようとしても、実行時エラーがでて関数での処理まで進めないはずです。
(エラーメッセージはご自身でお確かめください)
Function Convert2to10(Value As String) As Long Dim Ret As Long Dim K As Long Dim X As Long For K = 1 To Len(Value) If Mid(Value, Len(Value) - K + 1, 1) = "1" Then X = 2 ^ (K - 1) Ret = Ret + X End If Next K Convert2to10 = Ret End Function Sub CallTheFunc() Dim fuga As Long fuga = 1.100000010101E+31 Debug.Print Convert2to10(fuga) End Sub
ということなので、「オーバーフローの解消方法をご教授頂けないでしょうか」という以前のこととして、いろいろあますので。
よろしく、お願いいたします。
12239 : kurosukeさんのコメント (2020-07-02 06:27:54)
Functionプロシージャで32bitの2進数を10進数に変換する為のマクロを作成しましたが、「オーバーフロー」のエラーとなります。
引数Valueには「11000000101010000000000100000000」が渡される想定です。戻り値を長整数型にしているので、数値は範囲内だと思いますが、オーバーフローの解消方法をご教授頂けないでしょうか。
Function Convert2to10(Value As String) As Long Dim Ret As Long Dim K As Long Dim X As Long For K = 1 To Len(Value) If Mid(Value, Len(Value) - K + 1, 1) = "1" Then X = 2 ^ (K - 1) Ret = Ret + X End If Next K Convert2to10 = Ret End Function
7150 : 小川慶一の回答 (2016-10-02 16:36:09)
古口梨絵 さん:
本質的なところに立ち返ってコメントすると、どの単位で仕事を分割したいか、次第です。
>小川先生
>> このデモではとりあえず3行目から10行目にしてみたまでのことで、あんまり意味はないです。
>
>了解です。
>
>今回の演習だと、Functionプロシージャは抽象化されるけど、Subプロシージャは同じようなコードの繰り返しなので、抽象化されているようないないような・・・と動画を見た直後は思いましたが、
>例えば、For Next構文のfmとtoが異なるような繰り返しでは効果絶大なのでは!?ということに気づきました。
>業務の中で早く使ってみたいです!
7146 : 古口梨絵さんのコメント (2016-09-30 22:10:26)
小川先生
> このデモではとりあえず3行目から10行目にしてみたまでのことで、あんまり意味はないです。
了解です。
今回の演習だと、Functionプロシージャは抽象化されるけど、Subプロシージャは同じようなコードの繰り返しなので、抽象化されているようないないような・・・と動画を見た直後は思いましたが、
例えば、For Next構文のfmとtoが異なるような繰り返しでは効果絶大なのでは!?ということに気づきました。
業務の中で早く使ってみたいです!
7145 : 小川慶一の回答 (2016-09-30 15:53:31)
7143 : 古口梨絵さんのコメント (2016-09-30 14:24:13)
Functionプロシージャの演習について質問です。
抽象化というお話のなかで、
bgoukeiの第三引数を「3」、第四引数を「10」として設定していますが、「3」と「10」はどこから出てきた値なのでしょうか。
For Next構文から拾ってくるとすれば、「4」と「31」なのでは?と思うのですが。
実際にやってみると、やはり合計値が異なるので「4」と「31」かと。

本講座の動画一覧
-
【動画1】 式と戻り値1-データ型のおさらい
-
【動画2】 式と戻り値2-「式」と「戻り値」
-
【動画3】 式と戻り値3-「式」と「戻り値のデータ型」
-
【動画4】 式と戻り値4-「式」とは(その1)
-
【動画5】 式と戻り値5-「式」とは(その2)
-
【動画6】 式と戻り値6-戻り値を返す式、戻り値を返さない式
-
【動画7】 コレクションとインデックス
-
【動画8】 配列
-
【動画9】 静的配列
-
【動画10】 動的配列1-動的配列の基本
-
【動画11】 動的配列2-Preserveキーワード
-
【動画12】 動的配列3-演習
-
【動画13】 多次元配列の基本
-
【動画14】 多次元動的配列
-
【動画15】 多次元配列のサイズを調べる
-
【動画16】 配列操作の便利関数、オプション、その他
-
【動画17】 連想配列1-Dictionaryオブジェクトの仕様
-
【動画18】 連想配列2-Dictionaryオブジェクトの使用例
-
【動画19】 連想配列3-Microsoft Scripting Runtimeのへの参照設定
-
【動画20】 「名前付き引数」と「名前なし引数」
-
【動画21】 省略可能な引数とその初期値
-
【動画22】 引数のデータ型
-
【動画23】 Functionプロシージャ
-
【動画24】 引数がひとつまたは複数のFunctionプロシージャ
-
【動画25】 Functionプロシージャ演習中
-
【動画26】 引数として配列を受け取るFunctionプロシージャ
-
【動画27】 引数を受け取らないSubプロシージャと引数つきSubプロシージャ
-
【動画28】 Subプロシージャの基本構造
-
【動画29】 モジュールレベル変数との使い分け
-
【動画30】 補講1-ディクショナリーオブジェクトのさらなる活用
-
【動画31】 補講2-ディクショナリーオブジェクトの .Count プロパティ
-
【動画32】 補講3-連想配列によるオブジェクトへの参照設定 - 新しいキーに設定する場合
-
【動画33】 補講4-連想配列によるオブジェクトへの参照設定 - 既存の値を上書きする場合
-
【動画34】 補講5-複数セルの集合を作るための便利なメソッド2つ
-
【動画35】 補講6-連想配列演習-取引先ごとに取引金額の合計を算出する
-
【動画36】 補講7-ウォッチ式の活用
-
【動画37】 補講8-ウォッチ式で配列の状態を確認する
-
【動画38】 補講9-たった1行のコードでセルのデータを配列に投入する
コメント紹介
もっと見る