« 2010年8月 | トップページ | 2010年10月 »

2010年9月

2010年9月29日 (水)

特定の文字で区切られた文字列を分割して配列にいれる

もう少し詳しく言い換えると、
特定の文字(例えば空白やコンマなど)で区切られた文字列を
その特定の文字で分割して一次元配列にいれる。

これにはSplit関数を使います。
使い方の具体例を挙げます。

Split("1,2,3,4,5", ",")

これは、

配列の要素0 = 1
配列の要素1 = 2
配列の要素2 = 3
配列の要素3 = 4
配列の要素4 = 5

の配列になります。

1つ目の引数に分割して配列にしたい文字列を指定します。
2つ目の引数は、分割する文字列です。

上の例では文字列"1,2,3,4,5"を
","(コンマ)で分割して配列にします。
区切る文字は1文字以上でもよく、
"<BR>"でも区切ることができます。

Split関数の詳細はVBAヘルプにあります。

コードはこちら
変数aをウォッチウインドウで見ると
配列を確認できます。

Split関数使用例のコード:

Sub macro100929a()
'特定の文字(,)で区切られた文字列を
'区切りの文字で分割して
'一次元配列を作る
'配列が格納されたバリアント型 (Variant)を使う

    Dim Str As String
    Dim a As Variant
   
    Str = "5,6,7,8"
    a = Split(Str, ",")
     'ウォッチウィンドウで配列を確認できます
    Stop
   
End Sub

Sub macro100929b()
'特定の文字(<BR>)で区切られた文字列を
'区切りの文字で分割して
'一次元配列を作る
'配列が格納されたバリアント型 (Variant)を使う

    Dim Str As String
    Dim a As Variant
   
    Str = "5<BR>6<BR>7<BR>8"
    a = Split(Str, "<BR>")
   
    'ウォッチウィンドウで配列を確認できます
    Stop
   
End Sub

Sub macro100929c()
'特定の文字(,)で区切られた文字列を
'区切りの文字で分割して
'一次元配列を作る
'動的配列を使う

    Dim Str As String
    Dim a() As String '文字列型の配列を宣言
    Str = "5,6,7,8"
   
    '配列のサイズを指定
    ReDim a(UBound(Split(Str, ",")))
   
    '代入
    a = Split(Str, ",")
   
     'ウォッチウィンドウで配列を確認できます
    Stop
   
End Sub

2通りの配列の使い方が
いつもごっちゃになります。
さらに
かつてかじったJAVAの配列のかすかな記憶も入り混じり
毎回調べてしまいます。

次の記事は、
配列の使い方を整理したいと思います。

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

2010年9月18日 (土)

24時間以上を表す文字列をDate型に変換する

24時間以上を表す文字列とは、
"28:00"とか"32:12"などの文字列のことです。

これをDate型に変換するために
CDate関数を使って

CDate("28:00")

とするとエラーになります。
(実行時エラー'13':型が一致しません。)

念のため、
IsDate関数でDate型に変換できるかどうか調べてみる。

CDate関数を使う前に
IsDate関数でDate型に変換できるかどうか調べると
型が一致しなかった場合のエラーを防げます。

IsDate("28:00") = False

ちなみに

IsDate("00:00") = True
IsDate("23:59") = True
IsDate("23:59:59") = True
IsDate("24:00:00") = False

やはり24時間以上だと
CDate関数でDate型に変換できないようです。

ところが、
Excelのシートのセルに

28:00

と入力すると
セルの書式設定の表示形式が自動的に

[h]:mm:ss

になり、セルには

28:00:00

と表示され24時間以上で表示されます。
値も日付型になっています。

28:00:00
= 1900/1/1 4:00
= 1.16666666666667

Excel自体には24時間以上を表す文字列を
Date型に変換する機能があるにも関わらず、
VBAでそれを利用する方法が見つからなかったので
まわりくどい方法を1つ。

基本的な流れは、
24時間以上を表す文字列を
あるセルに入力して
Excelが自動で日付に変換した値を
取り出して使います。

まず、
CDateで変換できるものはCDateで変換します。

CDateで変換できない文字列を

24時間以上の文字列(例:"28:00")
その他の文字列(例:"abc")

この2つと想定します。

この2つの区別に
セルの書式設定の表示形式が
自動的に [h]:mm:ss になることを利用します。

コードはこちら

24時間以上を表す文字列をDate型に変換するコード:

Function CDate2(Str As String) As Variant
   
    'CDate関数で変換できるものはCDateで
    If IsDate(Str) Then
        CDate2 = CDate(Str)
        Exit Function
    End If
   
    Dim MyCell As Range
    Dim sh As Object
   
    Application.ScreenUpdating = False
   
    'Sheets("temp")がなければシートの追加
    For Each sh In Worksheets
        If sh.Name = "temp" Then
            GoTo NextStep
        End If
    Next sh
    Sheets.Add.Name = "temp"
   
NextStep:
    Set MyCell = Sheets("temp").Range("A1")
    MyCell.Clear
   
    MyCell = Str
   
    If MyCell.NumberFormat = "[h]:mm:ss" Then
        CDate2 = CDate(MyCell)
    End If

    Application.ScreenUpdating = True
End Function

Sub macro100918a()
'CDate2関数使用例

    Debug.Print CDate2("12:32")
    Debug.Print CDate2("28:00")
    Debug.Print CDate2("abc")
    Debug.Print IsEmpty(CDate2("abc"))
   
End Sub

このCDate2関数を使った結果の例:

CDate2("12:32") = "12:32:00"
CDate2("28:00") = "1899/12/31 4:00:00"
CDate2("abc") = ""

「その他の文字列」を入れたとき
CDate2関数が返す値は空白ですが、

CDate2("abc") = CDate2("0:00:00")

となり
"abc"と"0:00:00"の区別がつきません。

そこでCDate2関数をVariant型にして、
値が初期化されていないか調べる
IsEmpty関数を使えるようにしました。

IsEmpty(CDate2("12:32")) = False
IsEmpty(CDate2("28:00")) = False
IsEmpty(CDate2("abc")) = True
IsEmpty(CDate2("0:00:00")) = False

まあ
こんなややこしいことをしなくても、
24時間以上を表す文字列をDate型に変換する
関数なりメソッドなりを見つける日が
いつか来ると思います。

いままでも
しばしば、まわりくどいことをしてます。
当サイトを参考にするときはお気をつけて。

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

2010年9月 4日 (土)

『Excel VBAマスターブック 2003&2002対応 WindowsXP版』

きたみ あきこ (著):『Excel VBAマスターブック 2003&2002対応 WindowsXP版 』,毎日コミュニケーションズ ,2006/06

Excel VBAの基本から簡単な応用までカバーしている本。
「○○するには」形式の目次は大変わかりやすい
一方、巻末には索引もありリファレンスとしても使いやすい。
新刊で2000円を下回る良心的な価格が好印象。

初心者は一番最初から順に進めていくと理解が深まる構成。
基本がわかっている人にはリファレンスとして使えると思います。

説明が簡潔で、レイアウトが見やすい。

項目ごとに基本のプロシージャと
シンプルな応用のプロシージャが示されていて、
それぞれに実行前と実行後のExcelのウィンドウのカラー画像があり
わかりやすいです。

ユーザーホームの説明が特に詳しいと思います。

ユーザーホームに作成した
ボタンやテキストボックスなどのコントロールの
イベントプロシージャを利用した具体例が豊富です。
(ボタンを押したときに
テキストボックスに入力された文字をセルに入力するなど)

内容のボリュームの割に
本自体はコンパクトにまとまっていて
他のVBAのリファレンス系の本に比べると低価格で
費用対効果がかなり高いと感じられる本です。

VBAのリソースはヘルプやインターネットなどで豊富にありますが、
パラパラとめくって調べられる
一覧性に優れた紙媒体の
この本のようなリファレンス本は
手元に1冊あると便利ですよ。

時間を節約するか…
お金を節約するか…
ですね。

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

2010年9月 1日 (水)

時間帯で条件分岐

現在の時刻は

Time

で取得できます。

条件分岐にはIfステートメントを使います。

例えば、7時以降なら実行したい処理がある場合、

If "7:00" < Time Then

End If

のようにしたいですけど、
このままでは「"7:00"」の部分が文字列と判断されて
意図したように条件分岐できません。

「"7:00"」を時間として処理させるには
CDate関数でデータ型を日付にします。
この関数を使うと、

CDate("7:00") = 1899/12/30 07:00:00

という日時になります。

Debug.Print Format(CDate(Time), "yyyy/mm/dd hh:mm:ss")

を実行するとわかりますが、
Timeで取得した現在の時刻も日付は1899/12/30です。
同じ日付なので
CDate("7:00")とTimeを比較するとき日付は無視できます。
7時以降なら実行したい処理がある場合の有効な条件分岐は

If CDate("7:00") < Time Then

End If

になります。

次は、7時から17時30分の時間帯に処理したい場合の条件です。
論理演算子Andを使います。

If CDate("7:00") < Time And Time < CDate("17:30") Then

End If

現在の時刻が7:00より大きい
かつ
現在の時刻が17:30より小さい
このような場合にTrueになります。

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

« 2010年8月 | トップページ | 2010年10月 »