« 2010年9月 | トップページ | 2010年11月 »

2010年10月

2010年10月30日 (土)

Timer 関数を使って処理時間を計測する

Timer 関数を使って
プロシージャや一連の処理にかかる実行時間を計測したいと思います。

Timer 関数は正午からの経過時間を秒で返します。
Windows では小数点以下も返しますが、
Mac では返しません。
ですので Windows のみミリ秒単位での計測ができます。

下の例では、
まず最初に変数 MyTime に計測したい処理の実行前の Timer を入れます。
それから For 文で計測したい処理を num 回実行します。
ここでは100回実行します。

処理を num 回実行したあとで

MyTime = Timer - MyTime
(num 回実行するのにかかった時間) = (処理後の正午からの経過時間) - (処理前の~)

の式で MyTime に「num 回実行するのにかかった時間」をいれます。

これを num で割れば平均速度がわかります。

コードはこちら

Timer 関数を使って処理時間を計測するコード:

Sub macro101030a()
'プロシージャの実行速度を計測
'num回実行してその平均を出す

    Dim MyTime As Single
    Dim i As Integer
    Const num As Integer = 100
   
    MyTime = Timer
    For i = 1 To num
   
        '計測したい処理、プロシージャをいれる
        Call 計測したいプロシージャ名
       
    Next i
    MyTime = Timer - MyTime
   
    'イミディエイトウィンドウに表示
    Debug.Print "処理時間:" & Format(MyTime / num, "0.000000") & "秒"
   
End Sub

ということで、
これを使っていろいろと処理速度を調べてみます。

| | コメント (0) | トラックバック (0)

2010年10月23日 (土)

正多角形の内角の組合せ

さて、今回は厳密でない数学的テーマ。

1つの頂点に集まる正多面体の内角の総和が360度以外なら
立体的(平面以外)になります。

今回はその中でも
内角の総和が360度より小さくなる組合せのみを調べます。

iからmまでのアルファベットで5つのFor文を入れ子して
それぞれの組合せを総当りで調べます。
正多面体の内角の総和が360度より小さい組合せのみを
シートに記録します。

正n角形の内角は、180-360/nです。
定数MaxAngで角が最多の正多角形を指定します。
下の例では正8角形までになっています。

コードはこちら

内角の総和が360度より小さい組合せを調べるコード:

Sub macro101023a()
'正多角形の内角の組合わせ
'合計が360度より小さい組合わせを調べる

    Sheets.Add
    Cells(1, 1) = "合計角度"
    Cells(1, 2) = "正多角形1"
    Cells(1, 3) = "正多角形2"
    Cells(1, 4) = "正多角形3"
    Cells(1, 5) = "正多角形4"
    Cells(1, 6) = "正多角形5"
   
    Dim i, j, k, l, m
    Const MaxAng As Integer = 8
    Dim ang(5) As Integer '内角
   
    For i = 3 To 8
        ang(1) = 180 - 360 / i
        For j = i To MaxAng
            ang(2) = 180 - 360 / j
            For k = j To MaxAng
                ang(3) = 180 - 360 / k
                If ang(1) + ang(2) + ang(3) < 360 And _
                    ang(1) + ang(2) > ang(3) Then
                    Rows(2).Insert
                    Cells(2, 1) = ang(1) + ang(2) + ang(3)
                    Cells(2, 2) = i
                    Cells(2, 3) = j
                    Cells(2, 4) = k
                End If
                For l = k To MaxAng
                    ang(4) = 180 - 360 / l
                    If ang(1) + ang(2) + ang(3) + ang(4) < 360 Then
                        Rows(2).Insert
                        Cells(2, 1) = ang(1) + ang(2) + ang(3) + ang(4)
                        Cells(2, 2) = i
                        Cells(2, 3) = j
                        Cells(2, 4) = k
                        Cells(2, 5) = l
                    End If
                    For m = l To MaxAng
                        ang(5) = 180 - 360 / m
                        If ang(1) + ang(2) + ang(3) + ang(4) + ang(5) < 360 Then
                            Rows(2).Insert
                            Cells(2, 1) = ang(1) + ang(2) + ang(3) + ang(4) + ang(5)
                            Cells(2, 2) = i
                            Cells(2, 3) = j
                            Cells(2, 4) = k
                            Cells(2, 5) = l
                            Cells(2, 6) = m
                        End If
                    Next m
                Next l
            Next k
        Next j
    Next i
   
End Sub

| | コメント (0) | トラックバック (0)

2010年10月16日 (土)

2次元配列の使い方

記事「 配列の使い方を整理」で説明したように
以下の順番でみていきます。

1. Variant型の変数にArray関数を使って配列をいれる。
2.配列を宣言してそれぞれの要素を指定する。
    2-a. 固定長配列
    2-b. 動的配列

以下の例で使う2次元配列は3x5のサイズです。

配列の内容は
コードの最後でシートに書き出すようになっていますが、
要所要所でウォッチウィンドウで配列の状態を確認してみると
流れがわかります。

まず、1つ目からみます。

1. Variant型の変数にArray関数を使って配列をいれる。

2次元配列はめんどくさくてあまり使っていなかったので
深く考える機会も今までなかったのですが、
Array関数は1次元配列のためのもののようですね。

とりあえず入れ子状にしたら
2次元配列らしきものができました。
この方法に全く実用性はないと思いますが、
各要素を指定する変数が少し変わっていたので
面白いと思いました。

2次元配列の各要素の指定方法は
a(i, j) のようにするのですが、
Array関数を入れ子したこれは、a(i)(j)とします。

サンプルコードはこちら

2次元配列の使い方1のサンプルコード:

Sub macro101016a()
'2次元配列の使い方1(3x5)
'Array関数を使って

    Dim a As Variant
   
    'Array関数を入れ子にして2次元配列にする
    a = Array( _
            Array("(0, 0)", "(0, 1)", "(0, 2)", "(0, 3)", "(0, 4)"), _
            Array("(1, 0)", "(1, 1)", "(1, 2)", "(1, 3)", "(1, 4)"), _
            Array("(2, 0)", "(2, 1)", "(2, 2)", "(2, 3)", "(2, 4)") _
        )
       
    '配列の内容をシートに書き出す
    '各要素の指定方法に注目!
    Dim i As Integer, j As Integer
    Sheets.Add
    For i = 0 To UBound(a) '<=注目
        For j = 0 To UBound(a(i)) '<=注目
            Cells(i + 1, j + 1) = a(i)(j) '<=注目
        Next j
    Next i
   
End Sub

2つ目です。

2-a. 固定長配列

1次元配列と同様に
配列の宣言をしてFor文を使って各要素に値を入れる流れは同じです。

配列の宣言は次のようにします。

Dim a(2, 4) As String

これで3行5列の配列が宣言されました。
2次元配列では各要素にアクセスするために
For文を入れ子します。

For i = 0 To UBound(a, 1)
    For j = 0 To UBound(a, 2)
        a(i, j) = 何らかの値
    Next j
Next i

UBound関数の使い方にも注目。
1次元目の最大の添え字 = UBound(a, 1)
2次元目の最大の添え字 = UBound(a, 2)

サンプルコードはこちら

2次元配列の使い方2-aのサンプルコード:

Sub macro101016b()
'2次元配列の使い方2(3x5)
'固定長配列

    Dim a(2, 4) As String
   
    Dim i As Integer, j As Integer
   
    '配列に値を入れる
    For i = 0 To UBound(a, 1)
        For j = 0 To UBound(a, 2)
            a(i, j) = "(" & i & ", " & j & ")"
        Next j
    Next i
   
    '配列の内容をシートに書き出す
    Sheets.Add
    For i = 0 To UBound(a, 1)
        For j = 0 To UBound(a, 2)
            Cells(i + 1, j + 1) = a(i, j)
        Next j
    Next i
   
End Sub

最後は、

2-b. 動的配列

まず動的配列を宣言する。

Dim a() As String

次に、配列のサイズを指定する。

ReDim a(2, 4)

配列の各要素にアクセスする方法は
固定長配列と同様です。

サンプルコードはこちら

2次元配列の使い方2-bのサンプルコード:

Sub macro101016c()
'2次元配列の使い方3(3x5)
'動的配列

    Dim a() As String
   
    Dim i As Integer, j As Integer
   
    '配列に値を入れる
    'サイズを指定
    ReDim a(2, 4)
    For i = 0 To UBound(a, 1)
        For j = 0 To UBound(a, 2)
            a(i, j) = "(" & i & ", " & j & ")"
        Next j
    Next i
   
    '既存データを保持してサイズを再指定
    ReDim Preserve a(2, 5)
    For i = 0 To UBound(a, 1)
        For j = 0 To UBound(a, 2)
            If a(i, j) = "" Then
                a(i, j) = "added(" & i & ", " & j & ")"
            End If
        Next j
    Next i

    '配列の内容をシートに書き出す
    Sheets.Add
    For i = 0 To UBound(a, 1)
        For j = 0 To UBound(a, 2)
            Cells(i + 1, j + 1) = a(i, j)
        Next j
    Next i
   
End Sub

配列の使い方のモヤモヤが晴れて
すっきりしました。

Excelはシートを配列代わりに使えるので
配列を使わなくてもやっていけますが、
処理の速度のことを考えたら
一回一回セルに値を入れるのはよくないな~と思ってはいました。

まだ試作段階のプロシージャは
逐一、値の変化が見えた方が便利なので
ついついそのままでした。
よし、これからは最終段階では配列を使おう。

| | コメント (0) | トラックバック (0)

2010年10月 5日 (火)

1次元配列の使い方

配列の使い方を何回も調べてしまう人は
一度、頭の中で使い方を整理するといいかもしれません。

配列の使い方がはっきりしない理由は、
配列の使い方が大きく分けて2種類あることだと思います。
この2つの一部分と一部分が混ざって
間違った配列の使い方をして
結局、調べなおすということを
何回もしました。

そんな訳で、配列の使い方を整理したいと思います。
1次元配列を例にします。

2つの配列の使い方:

1. Variant型の変数にArray関数を使って配列をいれる。
2.配列を宣言してそれぞれの要素を指定する。
    2-a. 固定長配列
    2-b. 動的配列

まず、1つ目から整理します。

最初にVariant型で変数を宣言する。

Dim a As Variant

次にVariant型の変数aにArray関数で配列を代入する。

a = Array("a", "b", "c", "d")

この例の場合は、

UBound(a) = 3
a(0) = "a"
a(1) = "b"
a(2) = "c"
a(3) = "d"

といった配列になります。

1つ1つの要素を指定するには次のようにします。

a(1) = "z"

とすると、配列はこのように変わります。

a(0) = "a"
a(1) = "z"
a(2) = "c"
a(3) = "d"

For...Next ステートメントを使って各要素にアクセスするには
次のようにします。

Dim i As Integer
For i = 0 To UBound(a)
    a(i) = 何らかの値
Next i

サンプルコードはこちら

配列の使い方1のサンプルコード:

Sub macro101005a()
'配列の使用方法
'Array関数を使って
   
    Dim a As Variant
    a = Array("a", "b", "c", "d")
    a(1) = "z"
   
    'イミディエイトに表示する
    Dim i As Integer
    For i = 0 To UBound(a)
        Debug.Print "a(" & i & ") = " & a(i)
    Next i
   
     'ウォッチウィンドウで配列を確認できます
    Stop
   
End Sub

2つ目の配列の使い方は、配列を宣言する方法です。
配列には、固定長配列と動的配列があるので
2つに分けて整理します。

2-a. 固定長配列を宣言する。

Dim a(3) As String

この場合の配列は、要素数4の文字列型です。
宣言しただけの状態では、値は何も入っていません。

a(0) = ""
a(1) = ""
a(2) = ""
a(3) = ""

1つの要素を指定したり、各要素にアクセスする方法は
配列の使い方1と同様です。

サンプルコードはこちら

固定長配列の使い方のサンプルコード:

Sub macro101005b()
'固定長配列の使用方法

    Dim i As Integer
    Dim a(3) As String '固定長配列の宣言
    For i = 0 To UBound(a)
        a(i) = Chr(97 + i)
    Next i
   
    'イミディエイトに表示する
    For i = 0 To UBound(a)
        Debug.Print "a(" & i & ") = " & a(i)
    Next i
   
     'ウォッチウィンドウで配列を確認できます
    Stop
   
End Sub

2-b. 動的配列を宣言する。

Dim a() As String

次に、配列のサイズを指定する。

ReDim a(3)

この配列は上の固定長配列の例と同じになります。

サンプルコードはこちら

動的配列の使い方のサンプルコード:

Sub macro101005c()
'動的配列の使用方法

    Dim i As Integer
    Dim a() As String '動的配列の宣言
   
   
    ReDim a(3) 'サイズを変更
   
    For i = 0 To UBound(a)
        a(i) = Chr(97 + i)
    Next i
   
    'イミディエイトに表示する
    For i = 0 To UBound(a)
        Debug.Print "a(" & i & ") = " & a(i)
    Next i

   
     'ウォッチウィンドウで配列を確認できます
    Stop
   
End Sub

2次元配列の使い方は次の記事を参照してください。
記事「2次元配列の使い方

| | コメント (0) | トラックバック (0)

« 2010年9月 | トップページ | 2010年11月 »