以下の内容はhttps://www.limecode.jp/entry/fungo/048-arrays-and-numeric-typesより取得しました。


48本目:配列と数値型

Excel&VBA解説サイト「エクセルの神髄」様出題の問題集、
VBA100本ノック」に対する私の回答と解説のページです。

100本ノックの出題リストはこちらから
excel-ubara.com

出題:配列と数値型

#VBA100本ノック 48本目
引数が1次元または2次元配列の場合、以下の処理を行いVariantで返すFunctionを作成。
xxx (v as Variant) As Variant
・数値型は整数部のみにする(1.5→1, -1.5→-1)
・数値型以外(文字列、日付、その他)はそのまま
※配列以外と3次元配列以上もそのまま返してください。

テスト結果

◇ 出題ページはこちら

ソースコード

メインモジュール

Option Explicit

' 100本ノック048:配列と数値型
Function 配列内の数値を整数化(配列 As Variant) As Variant

    ' 配列以外はそのまま返す
    If IsArray(配列) = False Or _
       TypeName(配列) = "Range" Then
       配列内の数値を整数化 = 配列
       Exit Function
    End If

    ' 次元数ごとに場合分けして整数化
    Dim 結果配列 As Variant: 結果配列 = 配列
    Dim i As Long, j As Long
    Select Case Get配列の次元数(配列)
        Case 1
            For i = LBound(結果配列) To UBound(結果配列)
                If Is小数型(結果配列(i)) Then
                    結果配列(i) = Fix(結果配列(i))
                End If
            Next

        Case 2
            For i = LBound(結果配列, 1) To UBound(結果配列, 1)
                For j = LBound(結果配列, 2) To UBound(結果配列, 2)
                    If Is小数型(結果配列(i, j)) Then
                        結果配列(i, j) = Fix(結果配列(i, j))
                    End If
                Next
            Next

        Case Else
            Exit Function
    End Select

    配列内の数値を整数化 = 結果配列
    
End Function

' 小数を扱う型の判定
Function Is小数型(判定値 As Variant) As Boolean

    Select Case TypeName(判定値)
    Case "Single", "Double", "Currency", "Decimal"
        Is小数型 = True
    End Select

End Function

汎用関数モジュール

Option Explicit

' 配列の次元数の取得
' 参考:https://www.limecode.jp/entry/utility/get-array-dimension
Function Get配列の次元数(Arr As Variant) As Long

    ' 渡された変数が配列ではない場合は0を返すこととする
    If IsArray(Arr) = False Then Get配列の次元数 = 0: Exit Function

    ' エラーが出るまでUBoundを取得してみる
    Dim tmp
    Dim 次元数 As Long: 次元数 = 0
    On Error Resume Next
    Do While Err.Number = 0
        次元数 = 次元数 + 1
        tmp = UBound(Arr, 次元数)
    Loop
    On Error GoTo 0

    ' エラーが出たひとつ前の次元が求める次元数
    Get配列の次元数 = 次元数 - 1

End Function

解説

引数が配列であるかを確認し、その要素を整数化していく問題です。

処理自体は愚直にループして変換していくだけですね。


注意点が2つあり、まずひとつは「切り捨て」ではない点です。

‐1.5はInt関数では-2になってしまいますので、
ここではFix関数を使用する必要があります。


もうひとつの注意点は、IsArrayがRangeに対してもTrueになる点です。

単にIsArrayがTrueかどうかを判定するだけだと、
セル範囲が渡った場合にこの判定を突破してしまします。

大抵はその後実行されるUBound/Lboundがエラーで止まることが多いでしょう。


配列だけに処理を行いたい場合は、
今回のようにTypeName関数でRangeかどうかを判定してください。

詳しくはこちらの記事をどうぞ。




以上の内容はhttps://www.limecode.jp/entry/fungo/048-arrays-and-numeric-typesより取得しました。
このページはhttp://font.textar.tv/のウェブフォントを使用してます

不具合報告/要望等はこちらへお願いします。
モバイルやる夫Viewer Ver0.14