2017年4月12日水曜日

Outlookの自動操作

これまではVBAの基礎からIEの自動操作までを解説してきました。
今回はOutlookの自動操作についての説明をしていきたいと思います。

まずはこちらのコードを見てください。
Sub Sample()
Dim objOL As Object   'Outlook本体
Dim myNS As Object   'NameSpace
Dim myB As Object   '対象メールボックス
Dim myF As Object   '対象フォルダ
Dim myItem As Object    'メール本体
Dim bnam As String  'メールボックス名
Dim fnam As String  'ログイン情報のシートの予約メールフォルダ
Dim s As Integer
'bnamとfnamの変数の代入
bnam = Worksheets("情報").Range("A1").Value
fnam = Worksheets("情報").Range("A2").Value

'Outlookの起動
Set objOL = CreateObject("Outlook.Application")

'NameSpaceの代入
Set myNS = objOL.GetNameSpace("MAPI")

'メールボックスの代入
Set myB = myNS.Folders(bnam)

'メールボックスの対象のフォルダ階層まで移動
Set myF = myB.Folders("受信トレイ").Folders(fnam)

'myFまで移動したOutlookを表示
myF.Display

'myFのフォルダのメールの数だけ繰り返す
For s = 1 To myF.Items.Count
    DoEvents

'メールを変数に代入する
    Set myItem = myF.Items(s)
'メールの本文を切り取る
    h = Trim(myItem.Body)
'対象のセルに本文を貼り付ける
    Cells(s + 1, 1).Value = h
'メールの変数を空にする
    Set myItem = Nothing
'本文の変数を空にする
    h = ""
Next
MsgBox "終了"
objOL.Quit
Set objOL = Nothing
End Sub
上記のコードを実行すると、情報のシートのA1のセルに入れた名前のメールボックスの情報のシートのA2のセルに入れたフォルダにあるメールを、全てExcelへ取り出してきます。

例えば仕事でメールで届いたものを「今まで何件も何十件もExcelへ取り出していた」という方の場合、このマクロを覚えてしまえば全て自動でExcelに取り出してきます。
また今までマクロでと考えていた人でもネットで情報が少なくて出来なかった人などいるかと思います。

そういう人はこの解説をよく読んで自分なりに新しく開発してみるのも良いかと思います。

Outlookの起動~NameSpaceの代入


まずはOutlookの起動からNameSpaceの指定までを解説します。
'Outlookの起動
Set objOL = CreateObject("Outlook.Application")
'NameSpaceの代入
Set myNS = objOL.GetNameSpace("MAPI")
Set objOL = CreateObject("Outlook.Application")
ここはIE操作【IE起動~読み込み】を勉強している人はわかると思います。
objOLへCreateObjectで作ったOutlook.Applicationを代入し、Outlookを起動しています。

Set myNS = objOL.GetNameSpace("MAPI")
次のNameSpaceの指定は始めて見ますよね?
このNameSpaceはVBAでは基本的に使用しませんので、このコードを丸暗記してもらえれば大丈夫です。

ちなみに簡単にNameSpaceを説明すると、例えば2人のプログラマーがそれぞれのパーツを作って1つのプログラムを作る時、同じ名前の変数を二人ともが宣言していると、実際にプログラムを動かす時、それぞれの変数の名前がぶつかり合います。
そうして変数が衝突してしまうとエラーが起こってしまうので、そういう時にNameSpaceを使い、「AさんのAという変数ですよ」とプログラムに教えるわけです。

メールボックスの代入~対象フォルダの表示


次に自動で操作したいメールボックスの選択から自動操作の対象になるフォルダの表示までを解説します。
'メールボックスの代入
Set myB = myNS.Folders(bnam)
'メールボックスの対象のフォルダ階層まで移動
Set myF = myB.Folders("受信トレイ").Folders(fnam)
'myFまで移動したOutlookを表示
myF.Display
Set myB = myNS.Folders(bnam)
このコードは「メールボックスの変数に先ほど指定したネームスペースの中のbnamに代入した名前のフォルダを代入」という処理をしています。
つまりOutlook内のbnamのメールボックスを変数にしています。

Set myF = myB.Folders("受信フォルダ").Folders(fnam)
このコードでは「フォルダの変数に先ほど指定したメールボックスの受信フォルダの中のfnamに代入した名前のフォルダを代入」という処理をしています。
こちらも同じようにOutlook内のfnamのメールボックスを変数にしています。

myF.Display
これはmyFに代入したフォルダを可視化=見えるようにしています。
今までのIEの自動操作だと「Visible = True」として可視化していましたが、Outlookでは「.Display」を使います。

メールの取り出し


最後にメールの取り出し方です。
'myFのフォルダのメールの数だけ繰り返す
For s = 1 To myF.Items.Count
    DoEvents
'メールを変数に代入する
    Set myItem = myF.Items(s)
'メールの本文を切り取る
    h = Trim(myItem.Body)
'対象のセルに本文を貼り付ける
    Cells(s + 1, 1).Value = h
'メールの変数を空にする
    Set myItem = Nothing
'本文の変数を空にする
    h = ""
Next
For s = 1 To myF.Items.Count
このコードでは「1~myFのフォルダの中にあるメールの数だけ繰り返し」という処理をします。
IEの自動操作で言うところの「For Each」でオブジェクトの数だけ繰り返しをするイメージです。

DoEvents
これはIEの自動操作の読み込み待ちでも使っていたようにOSに処理を戻すということでPCを操作出来る状態にしてくれます。

Set myItem = myF.Items(s)
このコードでは「myItemにmyFのフォルダのs番目のメールを代入」という処理を実行しています。
今更ですが、ところどころに出てきているItemsとはフォルダ内のアイテム=メールになります。
勘の良い方はとっくに気付いてたでしょうけどね。笑

h = Trim(myItem.Body)
これは「hという変数に前後の空白を切り取った状態でmyItemのBody部分=本文を代入」ということになります。
例えばmyItem.Bodyをそのまま代入すると本文の最初や最後に空白があった場合、そのままセルの中に入れてしまうので、私が使う時には邪魔になるのでこのように削除しています。

Cells(s + 1, 1).Value = h
これはもう大丈夫ですよね?
s+1行目の1列目のセルにhに代入したメールの本文を貼り付けます。

Set myItem = Nothing
h = ""

この2つのコードはmyItemとhの変数の中身を空にしています。
これは念の為に2つの変数の中身を空にすることで誤って変数が上書きされないことを防ぐ為に入れました。
Outlookの自動操作はあまりしていないので不安なところがあるので確実に動いているかのチェックの為に入れています。

最後に


ここまでの操作が出来るようになったらメールの本文の取出しが出来るようになると思います。
例えばBodyを使用したら本文を指定することになりますが、Toを使用したら宛先を指定する事になります。
他にもOutlookに対するプロパティやメソッドがあるので、その辺についてはまた次の機会に説明したいと思います。

2017年4月11日火曜日

セルやワークシートの指定

VBAを組んでいく上で一番大事になるのがセルの指定やワークシートの指定です。
例えばA1のセルに何か文字を入れたい時にA1のセルを指定出来ないと、どう頑張っても文字は入れれないですよね?
なのでまず1番最初にセルやワークシートの指定方法を覚えましょう。

例1)Cells(1, 1).Value = "A1のセル"
例2)Range("A2").Value = "A2のセル"
例3)Worksheets("Sheet1").Activate

ValueやActivateについてはまた別記事で説明しますが、Valueは値、Activateはアクティブにするとだけ覚えておいてください。

では例1から説明しますね。

Cells


例1では【Cells(,)】を使用しています。
このCellsは縦軸, 横軸のセルを指定するということになります。
例1の場合は1行目の1列目のセル=A1のセルになってるということです。
数学の表で言うy, xの事です。

Range


次に例2の【Range("A2")】です。
これは簡単ですね。
Rangeは次の("")に入ってるA2のセルの事を指します。
つまり、A3を("")の中に入れたらA3のセルを指しますし、A4を("")の中に入れたらA4のセルを指します。

Worksheets


最後に例3の【Worksheets("Sheet1")】です。
まずWorksheetsのsは「シートという物の中からこのシートを選びますよ」という事で複数の物から1つの物を選ぶので、複数形のsの付け忘れに注意してください。
次の("Sheet1")についてはこれもRangeと同じで("")の中のシートを指す事になるので、シート名をそのまま入力してください。

最後に


上記の3例の他にもR1C1形式を使ったセルの指定や、Rangeの中にRangeを入れたりと複数の段階を踏む事もありますのでその辺についてはまた別の機会に説明します。

IE操作【リスト選択~送信ボタン】

前回のIE操作【inputタグへの値の入力】ではユーザーフォームのHTMLで、inputのタグへの値の入力、チェックボックスやラジオボックスへのチェックを入れるところまでやりました。
今回の記事では、textareaのタグやselectタグの選択、IEの操作が終わった後の処理などについて解説していこうと思います。

では前回同様にサンプルページのユーザーフォームより、「メモ欄、Excelのバージョンのリスト、送信ボタン、IE終了後の処理」の操作について解説していきたいと思います。
フォームの入力【コード】より下記のコードの部分を解説していきます。
    'メモ欄への記載
        
    'objIEのHTMLの中からtextareaのタグをobjに代入しながら確認
    For Each obj In objIE.Document.GetElementsByTagName("textarea")
        
        'objに代入されたtextareaのタグのIDがnoteの場合
        If obj.ID = "note" Then
            'objに代入されたtextareaのタグにB7のセルの値を入れる
            obj.Value = Worksheets("情報").Range("B7").Value
        End If
    Next
    
    'Excelのバージョンの選択
    
    'objIEのHTMLの中からselectのタグをsltに代入しながら確認
    For Each slt In objIE.Document.GetElementsByTagName("select")
        
        'sltに代入されたselectタグのIDがversionだった場合
        If slt.ID = "version" Then
            'sltのタグに含まれるoptionのタグをoptに代入しながら確認
            For Each opt In slt.GetElementsByTagName("option")
                
                'optに代入されたoptionタグのInnerTextがB6のセルと同じだった場合
                If Trim(opt.InnerText) = Worksheets("情報").Range("B6").Value Then
                    'optに代入されたoptionタグを選択
                    opt.Selected = True
                End If
            Next
        End If
    Next
    
    '送信ボタンのクリック
    
    'objIEのHTMLにあるinputタグをobjに代入しながら確認
    For Each obj In objIE.Document.GetElementsByTagName("input")
        
        'objに代入されたinputタグのvalueの値が送信だった場合
        If Trim(obj.Value) = "送信" Then
            'objをクリック
            obj.Click
        End If
    Next
    
    '終了のメッセージボックスを表示
    MsgBox "終了"
    
    'objIEに代入したInternetExplorerを閉じる
    objIE.Quit
    
    'objIEを空にする
    Set objIE = Nothing
End Sub

テキストエリアへの入力


では上記コードより最初にメモ欄への記載について解説したいと思います。
今回もHTMLとVBAのコードを確認しながら解説していきた思いますので、まずは下記HTMLとVBAのコードをご覧ください。
メモ欄のHTML
<th>メモ欄</th>
<textarea id="note" rows="3" cols="40"></textarea>
VBAのコード
'メモ欄への記載
'objIEのHTMLの中からtextareaのタグをobjに代入しながら確認
For Each obj In objIE.Document.GetElementsByTagName("textarea")
    'objに代入されたtextareaのタグのIDがnoteの場合
    If obj.ID = "note" Then
        'objに代入されたtextareaのタグにB7のセルの値を入れる
        obj.Value = Worksheets("情報").Range("B7").Value
    End If
Next
結論を言うと、こちらのコードは前回とほとんど同じです。
取得するタグがtextareaになっているだけという感じなので解説は軽くにします。

【For Each obj In objIE.Document.GetElementsByTagName("textarea")】
これは前回のinputタグを取得した時と同じで、objの変数にobjIEのHTMLの中からtextareaというタグを取得していきます。
これはもうわかりますよね?

【If obj.ID = "note" Then】
こちらも上記と一緒で前回解説したobjに代入されたタグのIDがnoteだった時に次の処理に行くという内容です。

【obj.Value = Worksheets("情報").Range("B7").Value】こちらも前回のハンドルネームと一緒で「noteというIDのtextareaタグにB7のセルの内容を入れますよ」という事なので、もうわかりますよね?

この様にHTMLのタグが違ってもIDなどから処理したい要素を探し、Valueなどで値を入れるということは一緒なので、この事を覚えておいてください。

リストボックスの選択


では次にExcelのバージョンのリスト選択について解説します。
ExcelのバージョンのHTML
<th>Excelのバージョン</th>
<select id="version">
<option value="2016">Excel2016</option>
<option value="2013">Excel2013</option>
<option value="2010">Excel2010</option>
<option value="2007">Excel2007</option>
</select>
VBAのコード
'Excelのバージョンの選択
'objIEのHTMLの中からselectのタグをsltに代入しながら確認
For Each slt In objIE.Document.GetElementsByTagName("select")
    'sltに代入されたselectタグのIDがversionだった場合
    If slt.ID = "version" Then
        'sltのタグに含まれるoptionのタグをoptに代入しながら確認
        For Each opt In slt.GetElementsByTagName("option")
            'optに代入されたoptionタグのInnerTextがB6のセルと同じだった場合
            If Trim(opt.InnerText) = Worksheets("情報").Range("B6").Value Then
                'optに代入されたoptionタグを選択
                opt.Selected = True
            End If
        Next
    End If
Next
【For Each slt In objIE.Document.GetElementsByTagName("select")】
上記のコードも今までの解説とほとんど同じで、sltの変数にobjIEのHTMLの中からselectのタグを取得しています。
これはもう簡単ですよね?

【If slt.ID = "version" Then】
これもまたまた今まで通りで、sltの変数に入ったselectタグのIDがversionの時、次の処理をします。

【For Each opt In slt.GetElementsByTagName("option")】
やっとここから今までとは違った処理をします。
まず、optの変数にoptionを代入することはわかると思います。

ただ、ここが違います。
【slt.GetElementsByTagName】
このように先程sltに代入したタグの中にあるoptionというタグを取得するようにしています。

まず、HTMLを見ながら確認してもらうと分かりやすいと思うのですが、<select>~</select>の間に<option>~</option>というタグが挟まれていると思います。
このようにselectタグで囲まれているoptionタグの中の値がリストのパーツになります。

では上記のslt.GetElementsByTagNameとselectタグに挟まれたoptionタグをあわせて考えると、sltにはselectタグが代入されています。
その「sltに代入されたselectタグの範囲からoptという変数にoptionのタグを代入していく」という処理をしていっているのです。

注意点としては、Documentを入れないことです。
Documentを入れてしまうとHTML全体から探してしまうので、他にoptionタグがあった時、全てのoptionタグに対して処理をしてしまうので、sltに代入されたリストだけを操作したい時には、必ずDocumentを抜いてあげましょう。

ボタンのクリック


次は送信ボタンの実行について説明します。
送信ボタンのHTML
<input  onclick="inf(frm)" id="date" value=" 送信 " type="submit">
VBAのコード
'送信ボタンのクリック
'objIEのHTMLにあるinputタグをobjに代入しながら確認
For Each obj In objIE.Document.GetElementsByTagName("input")
    'objに代入されたinputタグのvalueの値が送信だった場合
    If Trim(obj.Value) = "送信" Then
        'objをクリック
        obj.Click
    End If
Next
こちらは前回のIE操作【inputタグへの値の入力】で解説した、ラジオボックスの選択とほとんど一緒です。

【For Each obj In objIE.Document.GetElementsByTagName("input")】
こちらはもうお分かりですよね?
objにobjIEのHTMLからinputタグを代入していきます。

【If Trim(obj.Value) = "送信" Then】
こちらが少しだけ違いますが、objに代入されたinputタグのvalueの値が送信だった時に次の処理に進みます。

【obj.Click】
こちらもわかりますよね?
objをクリックするだけです。

前回の記事からここまで理解できたら、ユーザーフォームの操作は出来るようになってると思います。
何度も言いますが、基本の流れは
【For Eachで変数へタグを代入し、そのタグが操作したいタグかをIfで確認する】
という流れになります。
この事を覚えたら、後はHTMLを確認してどのタグの何を確認して処理をするかを考えるという事になります。

オブジェクトの解放


最後に1つ、やっておかないといけないことがあります。
'objIEに代入したInternetExplorerを閉じる
objIE.Quit
'objIEを空にする
Set objIE = Nothing
【objIE.Quit】でIEを閉じます。
次の【Set objIE = Nothing】が大事で、objIEにInternetExplorerを代入したままだと、objIE.QuitでIEを消しても、PCのプロセスとしては起動したままになります。
なのでSetを使い、objIEの中身をNothingで空にして終了してください。

またマクロ実行後にInternetExplorerを目視で確認したい時もあると思います。
そういう時にはobjIE.Quitは省くことでIEを閉じないように出来ますので、必要に応じてobjIE.Quitは入れてください。
ただし、Set objIE = Nothingは入れておくことでマクロからIEを解放できますので、こちらはIEの自動操作をする場合、必ず最後に入れておいた方が良いと思います。

最後に


このIEの操作の解説はいかがでしたか?
結果実際に動かして、何をしているかを確認しながら理解することが一番覚えれるので、このブログを参考にしながら、コピペでもいいので動かしてみて、分からなければコメントなどで質問頂ければお答えしますので実践してみてください。

次からはIE上の表の出力を解説していきたいと思います。

IE操作【IE起動~読み込み】

では前回のIEの自動操作の1つ目のボタンに登録しているマクロの解説をしていきたいと思います。
今回解説する部分はフォームの入力【コード】から抜き出してきた下記のコード部分です。
Sub IE操作()
Dim objIE As Object
Dim obj As Object
Dim slt As Object
Dim opt As Object
Dim s As Integer
Dim hname As String
Dim brd As String

'hnameの変数にB2のセルの値を代入
hname = Worksheets("情報").Range("B2").Value

'pasの変数にB3のセルの値を代入
brd = Worksheets("情報").Range("B3").Value

'InternetExplorerをobjIEに代入し、IEのプロセスを起動
Set objIE = CreateObject("InternetExplorer.Application")
    
    'IEを可視化するか = はい
    objIE.Visible = True
    
    'IEのリンク先URLは情報のシートのB1のセルのURL
    objIE.Navigate Worksheets("情報").Range("B1").Value
    
    'IEの表示待ち
    wait objIE
Sub wait(objIE As Object)
'objIEに代入されたInternetExplorerがビジー状態、もしくは読み込み待ちの間、処理を待つ
Do While objIE.Busy Or objIE.ReadyState < 4
    DoEvents
Loop
End Sub
上記のコードを解説していきたいのですが、1つの記事だとあまりに長くなりますので分けて解説しようと思います。

変数宣言~代入


まずは変数です。
もう大丈夫だと思いますが、おさらいという事で解説していきます。

Dim objIE As Object  =  InternetExplorerのオブジェクトなので略してobjIE
Dim obj As Object    =  オブジェクトの代入の際に使うためオブジェクトを略してobj
Dim slt As Object    =  IEを操作する際のHTMLのタグにあるselectを略してslt
Dim opt As Object    =  IEを操作する際のHTMLのタグにあるoptionを略してopt
Dim s As Integer     =  繰り返しの際に使う変数でStartの意味からs
Dim hname As String  =  HandleNameを略してhname
Dim brd As String     =  BirthDayを略してbrd

というように自分で使いやすい名前で変数宣言しています。

次に変数の代入ですが、下記のほかにもForやFor Eachでの代入もありますが、そちらはForやForEachの解説の際に説明していきます。

hname = Worksheets("情報").Range("B2").Value
brd = Worksheets("情報").Range("B3").Value
Set objIE = CreateObject("InternetExplorer.Application")

上記3つありますが、以前の変数の代入【Dim】でも解説していますが、代入する型の違いから覚えることは2種類だけです。

IEの起動~状態~サイトへのアクセス~読み込み待ち


Set objIE = CreateObject("InternetExplorer.Application")上記の変数の代入ではオブジェクトを代入するので、変数名の前にSetをつけて「Set 変数名 = 代入するオブジェクト」となります。
また、【CreateObject("")】は、そのまま英語を訳してオブジェクトを作成するということになりますので、オブジェクトを作成する際に使用します。
今回はIEを起動するのでIEのオブジェクトの作成が必要になりますのでCreateObjectでInternetExplorer.Applicationを作成してます。

他の2つに関しては変数に文字列を代入するのでSetなどは使わず、「変数名 = 代入する値」という事になります。

次の【objIE.Visible = True】については、作成したオブジェクト=IEのウィンドウを表示する
上記の色分けの様にIEの可視化をするかしないかになります。
もし可視化しない場合はTrueの部分をFalseにしてあげる事でウィンドウが表示されない状態になります。

次に【objIE.Navigate Worksheets("情報").Range("B1").Value】です。
これは「IEでどこどこのサイトにアクセスしてください」という命令になります。
「情報のシートのB1のセルにあるURLにNavigateで行きますよ」という意味になります。
また、直接URLを指定する場合はobjIE.Navigate "URL"というように""で囲んだURLを記載します。

最後に【wait objIE】ですが、先に【Sub wait(objIE As Object)】を理解した上で解説しないと難しいと思いますので、そちらを先に解説します。
また、Subプロシージャの呼び出しについて理解していると次に進みやすいと思いますので、こちらのSubプロシージャの呼び出しもあわせて確認するといいかもしれません。

上記のwaitというSubプロシージャ内で処理している内容を簡潔に説明すると、「IEが読み込みをしている最中、もしくはビジー状態で動かない時、DoEvents関数でOSに処理を戻す事で読み込み待ちをしている」という状態になります。

この処理をしないでIEの操作をするとどうなるかというと、IEがページを読み込んでいないのに、次のマクロの処理に入ってしまうので、意図しない操作をしてしまうことになります。
なので正確な処理をするためにもwaitというSubプロシージャの内容は覚えておいてください。

では上記を踏まえた上で【wait objIE】について解説します。
これは「SubプロシージャをSubプロシージャから呼び出して処理をする」ということになります。
どういうことかというと【Sub IE操作()】を実行している中で【Sub wait(objIE As Object)】を呼び出して実行しているのです。

表記については【Subプロシージャ名 受け渡す変数名】となります。
実行する側のプロシージャにも受け渡される変数を宣言しないといけないのですが、その変数を宣言する場所が、Sub プロシージャ名()の括弧の部分になります。

ここが最初のうちは少し慣れないと思うのですが、SubプロシージャからSubプロシージャを呼び出す理由としては、IEの操作をする際、ページが変わる度に読み込み待ちの処理を入力すると大変なので、なら1つだけSubプロシージャとして書いておいて、読み込み待ちの処理をする度にSubプロシージャを呼び出そうという事です。

最後に


VBAを勉強始めたばかりの時は、ここまでの解説でもかなり難しく感じると思いますが、実際に実行したりHTMLを見てみることで感覚を掴むのが一番早い上達方法だと思いますので、難しく考えず1つ1つゆっくり進んでみてください。

では次回は値の入力について解説していきたいと思います。

VBAの基礎用語

記事の順番がバラバラですが、VBAの基本文法でも少し触れているのですが、プロパティやメソッド、ステートメントやプロシージャといった用語が出てきています。

この用語の意味を簡単にですが、解説していけたらと思います。
まず、ここでは6種類の用語を説明したいと思います。

1.プロシージャ(Sub~End SubやFunction~End Function等)
2.オブジェクト(セルやワークシート、ワークブック等)
3.ステートメント(If~End IfやFor~Next等)
4.プロパティ(ValueやName等)
5.メソッド(SelectやMove等)
6.関数(MidやTrim等)

この6種類の用語を覚えると、コーディングする際に「何が足りてないか」や「何をしたいか」等を調べる際にも役に立ちます。

ではこの用語を1つずつ説明していきたいと思います。

プロシージャ


プロシージャとは主に1つのコードの集合体です。
つまりマクロ本体のことです。
Sub a()
Dim s As Integer
b s
MsgBox "終了"
End Sub

Sub b(s As Integer)
s = 1
MsgBox s
End Sub
上記を実行すると最初に「1」と表示されて次に「終了」と表示されると思います。
そこはおいといて、これは2つのプロシージャを実行しています。
つまりSubの塊の数=プロシージャということです。
他にもFunctionもプロシージャに含まれます。

オブジェクト


オブジェクトとは操作対象になる物の事です。
例えばExcelのシートやブック、セルもオブジェクトですし、IEの自動操作する時のIE本体やサイトのボタンなどもオブジェクトに含まれます。
Sub a()
Worksheets("sample").Select
Range("A1").Select
End Sub
このWorksheetsやRange等がオブジェクトになります。
VBAの基本文法の記事で詳しく説明しているのですが、VBAの基本的な文法としては「オブジェクト.プロパティorメソッド」となっており、このオブジェクトが操作対象、プロパティorメソッドが操作方法というようになっています。

ステートメント


ステートメントとはマクロの処理方法です。
例えばIf~Else~EndIfやFor~Nextの様に繰り返しや条件などを指定し、マクロを実行する際の動きになります。
Sub a()
For s = 1 To 10
    Cells(s, 1).Value = s
Next
End Sub
このFor~Nextの部分がステートメントです。
Forでは繰り返しを、Ifでは条件分岐を、とマクロがどういう処理を行うかを決める部分がステートメントと呼ばれます。

プロパティ


プロパティとは操作対象に対する情報の部分に当たります。
例えばValueでは操作対象(オブジェクト)の値を指定、もしくは取得します。
Sub a()
Range("A1").Value = "ここだよ!"
MsgBox ActiveSheet.Name
End Sub
このValueとNameがプロパティです。
Range("A1").Value = "ここだよ!"
上記のコードは「A1のセルの値を「ここだよ!」にしてください」という意味になります。
MsgBox ActiveSheet.Name
上記のコードは「メッセージボックスに今選んでいるシートの名前を出してください」という意味になります。
このように値や名前などの情報がプロパティになります。

メソッド


メソッドはプロパティに似ているのですが、操作対象に対する動きの部分に当たります。
例えばSelectでは操作対象(オブジェクト)を選択します。
Sub a()
Worksheets("Sheet1").Select
Range("A1").Select
End Sub
上記のコードのようにシートやセルというオブジェクトに対する選択という動きがメソッドになります。
他にもわかりやすいもので言うとMoveは英語の意味そのままに動きなのでメソッドになります。

関数


関数とはプロパティなどの情報を処理し、形を変える操作の部分に当たります。
例えばTrimではValueやInnerTextなどで取得した値の前後にあるスペースを削除する操作をします。
Sub a()
Range("A1").Value = " 空白があるよ? "
MsgBox Trim(Range("A1").Value)
End Sub
このMsgBox Trim(Range("A1").Value)では「 空白があるよ? 」ではなく「空白があるよ?」がメッセージボックスでは出力されます。
A1のセルの文字の前後のスペースをTrimでは削除してくれますのでスペースが入っていない状態の文字が出力されるのです。

この様に情報に対する処理をし、形を変えた状態で出力する操作をしているのが関数です。
この変更前の情報を引数(ひきすう)といい、形が変わった状態を戻り値(もどりち)と言います。

最後に


最後に上記をまとめると
プロシージャ・・・コードの集合体
ステートメント・・・処理方法
プロパティ・・・情報
メソッド・・・動き
関数・・・操作 

ということになります。

この事を覚えてVBAの基本文法を見ると意味がわかりやすくなると思います。

2017年4月7日金曜日

VBAの基本文法

突然ですが、例えば喋る時や文字を書く時、英語などでも文法って学校行ってた頃に散々先生達からよく言われたと思います。笑
VBAでも日本語や英語等の様にパソコンに対しての文法があるのです。

人間同士なら予想しあったり感情で伝えることが出来ますが、パソコンを相手にした時にはそうはいきません。
パソコンではあらかじめ言語を作った人達によって文法が決められており、その文法から外れてしまうとエラーという形で「伝わりませんよ~」と返ってくるのです。

ではその文法から外れない為にも簡単にですが、基本的な文法を2つ紹介したいと思います。

例)Range("A1").Value = "ここに文字を入れてね?"

上記の例の様にコードを書いて実行するとExcelのA1のセルに「ここに文字を入れてね?」と文字が入力されます。
このコードを日本語でわかりやすく訳すと「A1のセルの値はここに文字を入れてね?にしてね」という意味になります。

このオレンジの文字の部分はオブジェクトと呼ばれるもので、実際に人間が操作するもの、例えばA1のセルもそうですし、ここで紹介してるようにIEの操作をする時のIE本体だったりもオブジェクトと呼ばれます。
イメージとしては既存の箱やパーツのようなものです。

次の緑の文字の部分はプロパティやメソッドという部分になります。
このプロパティやメソッドはオレンジのオブジェクトに対しての動作や情報等になります。
例えば今回のValueで言うと、A1のセルというオブジェクトの値がプロパティになります。

次の赤の文字の部分は演算子と呼ばれ、数学で使うような「+-*/=」等の記号が入ります。
今回の場合は、上記リンクの代入演算子の部分にある「=」で「右を左に入れる」という動作をしています。
他にもIfステートメント等では不等号(<>)等も使うことがあります。

最後に水色の文字の部分は代入される値になります。
Ifステートメントの時は左に対する条件になりますし、変数の代入の時には代入される値になるように、この部分は必要に必要に応じて変わります。

例えば【If Range("A1").Value = Range("B1").Value Then】と書いた場合、水色の部分は上記のオレンジと緑の部分と同じ文法になります。
この様に水色の部分は左に対する物なので、内容が変わる部分になります。

まとめると【オブジェクト.プロパティorメソッド】という文法が出来上がります。
赤の部分や水色の部分はステートメント等によって必要がない場合もありますので、まずは上記の形を覚えてください。

上記の様にたった2つのポイントだけがVBAの文法になります。
英語とかみたいに「~は~で~・・・」みたいに長々と覚える必要がないので簡単ですよね?笑

ただし、IEの操作をする時やシートやブックの操作が入る時等はオブジェクトが複数になることがあります。

例)Workbooks("sample.xlsm").Worksheets("sample").Range("A1").Value

上記の様に「sample.xlsmというブックのsampleというシートのセルA1の値」というように【オブジェクトのオブジェクトのオブジェクトのプロパティ】という文法になります。

これもまとめてしまうと「3つのオブジェクトのプロパティ」ということなので、「オブジェクト.プロパティ」という言い方も出来てしまうので、基本として【オブジェクト.プロパティ】を覚えておいてください。
また、この事を意識してこれからのコードを見ていくと、「どういうものをどう動かしているか」という事が理解しやすくなると思います。

2017年3月23日木曜日

もしも○○の時【If】

今回は【If】について解説していきたいと思います。

前回の答え


がその前に、前回の練習問題の答えは下記のコードになります。
Sub 繰り返し()
Dim s As Integer
For s = 1 To 20 Step 2
    Cells(s, 1).Value = s
Next
End Sub 
少し解説をすると、4行目【Cells(s, 1).Value = s】の部分では、セルのs行目の1列目=1行目の1列目のセルにsの値=1を入力します
2回目の繰り返しでは、sの値をプラス2ずつ進んでいきますので、2回目の繰り返しは3行目の1列目=A3のセルにsの値=3を入力します。
最後にsの値が20を超えたら繰り返しが終わりますので、Stepで2ずつプラスで進んでいると最後のsの値は19になりますので、19行目で処理を終了します。

この繰り返しについてはマクロの基本の動作として役に立ちますので、ぜひ覚えてくださいね。

If~End If


では【If】の解説に入りたいと思います。
まず【If】とは英語で「もしも」という意味を持っているそのままの意味でVBAでも使われます。
Excelの関数をやってる人はわかりやすいですよね。

例)If a.Value = "正解" Then
   MsgBox "正解"
  End If

上記の例を見ていきましょう。
まず【If a.Value = "正解" Then】の部分です。
これは日本語に訳すと「もしも:aの値が:正解:の時」という訳になります。
:で区切ってる位置をそのままIfの分に当てはめてあげるとわかると思います。

次の【MsgBox "正解"】はメッセージボックスに正解の文字を表示するだけになります。

最後の【End If】の部分に関してはEndの意味の通り、Ifステートメントの終わりを表します。

このIfに関してはよく使われますが、簡単なので多分すぐにクリアできると思います。

If~ElseIf~Else~End If

ただ、上記の例だとTrue(真)の場合しかかかれてないですよね?
ExcelのIf関数でも一緒ですが、False(偽)の場合はどう書くかというと

例)If a.Value = "正解" Then
    MsgBox "真"
  ElseIf a.Value = "不正解" Then
    MsgBox "真"
  Else
    MsgBox "偽"
  End If

上記の例の様に【Else】を使います。
まず【If a.Value = "正解" Then】の部分に関しては最初の解説と一緒なので省きます。

次の【ElseIf a.Value = "不正解" Then】ではIfがElseIfになっています。
「1行目のIf文がTrue(真)じゃなかった時:aの値が不正解:だったら」という順番になります。

最後の【Else】ですが、これはIfのある文で「Trueが一つもなかった時=False(偽)だった時」を表します。
なので上記の例だと「変数aの値が正解、もしくは不正解の時=Ifの返答がTrueになる時」はメッセージボックスには「真」が表示され、「どちらでもなかった時=Ifの返答がFalseになる時」はメッセージボックスには「偽」が表示されます。

練習問題


では最後に練習問題です。
A1~A10までのセルに1~100までの好きな数字を入れてください。
1.セルの値が80以上の場合は「よく出来ました」を表示
2.セルの値が50以上80未満の場合は「あと一歩」を表示
3.セルの値が50未満の場合は「もう少し頑張りましょう」を表示
上記3つの条件をB1~B10までのセルに自動で入力されるマクロを組んでください。
ヒントは前回の繰り返し【For】を使用し、上記のIfの解説を応用すると組めると思います。

このIfステートメントは次回使用しますので、覚えたら次の繰り返し【For Each】へお進みください。

繰り返し【For Each】

今回はForEachについて説明します。
最後に良いお知らせもあるので見てみてくださいね。

前回の答え


では、まずこちらも前回と同様に練習問題の解説から入りたいと思います。
正解のコードは下記になります。
Sub 評価()
Dim s As Integer
For s = 1 To Range("A1").End(xlDown).Row
    If Cells(s, 1).Value >= 80 Then
        Cells(s, 2).Value = "よく出来ました"
    ElseIf Cells(s, 1).Value >= 50 Then
        Cells(s, 2).Value = "あと一歩"
    Else
        Cells(s, 2).Value = "もう少し頑張りましょう"
    End If
Next
End Sub
まず繰り返しの部分ですが、【For s = 1 To Range("A1").End(xlDown).Row】と入力していますが、Range("A1").End(xlDown).Rowの部分は10でも正解です。
以前セルの範囲選択と可変式選択で説明したEnd(xlDown).Rowを使うことで可変式の範囲選択にする事ができますので、もし11行目にも入力していた場合、11行目も処理してくれるようになります。
このようにEnd(xlDown).Rowは自動で処理範囲を変えてくれるので大変便利です。
なのでぜひ覚えて活用してくださいね。

ではIf文の解説に戻って、1つ目の【If Cells(s, 1).Value >= 80 Then】ですが、これは「1列目1行目のセル=A1のセルの値が80以上の場合」という事になり、次の行の【Cells(s, 2).Value = "よく出来ました"】では「IfがTrue(真)の時、2列目1行目のセル=B1のセルによく出来ました」を入力する事になります。

【ElseIf Cells(s, 1).Value >= 50 Then】は1つ目と同じで値が50に変わっただけになります。

最後の【Else】ですが、こちらは「上記2つの条件に当てはまらなかった=False(偽)の時」ということで、今回の場合、49以下の時という事になります。
このように最後の条件はElseのみの入力でFalse(偽)を取得する事で処理が出来るなら、コードが短くなりますので、Flase(偽)を活用すればいい時はElseだけの使用にして、コードを短くしてあげましょう。

For Each

では話を戻して【For Each】の解説に入りたいと思います。
まず、For Eachの基本動作として「変数宣言したオブジェクトに繰り返したい範囲のオブジェクトを代入しながら繰り返しの範囲が終わるまで繰り返す」という動作をします。

このFor Eachに関しては、このブログの最終目標であるInternetExplorerの自動操作で確実に使うことになります。
上記の「」の中を理解しないとInternetExplorerの自動操作は出来ないので、確実に理解してください。
文字の色でグループ分けしてますので、解説の色とあわせながら進んでいくとわかりやすくなると思います。
では例題として下記のコードを見てください。

例)Sub オブジェクトの検索()
  Dim a As Object
  For Each a In Range("A:A")
    If a.Value = "ここだよ!" Then
          MsgBox "ここだよ!が入っているのは " & a.Address & " です。"
      End If
  Next
  End Sub

まずは【For Each a In Range("A:A")】から説明したいと思います。
For Eachの基本の形として【For Each オブジェクト変数 In 繰返し範囲のオブジェクト】という表記をします。
上記の例でいうと、オブジェクト変数の部分はDimを使って変数として宣言されている、aが当てはまります。
繰返し範囲のオブジェクトの部分は、「どのオブジェクトを繰り返したいか」になりますので、今回Range("A:A")の範囲を繰り返すようにしています。

次に【If a.Value = "ここだよ!" Then】に関しては、「変数aのオブジェクトに入ってるセルの値が「ここだよ!」の場合」という事になります。

最後に【MsgBox "ここだよ!が入ってるのは " & a.Address & " です。"】です。
こちらはオブジェクトaのセルの位置をメッセージボックスで表示しているだけになります。

上記のまとめとして、For Eachは「緑の文字の範囲を順番に、青の文字に入れて処理をしていく」という事になります。
For EachにIfを組み合わせる事で「aに代入されたオブジェクトが何々の時」という処理を実行できるのです。

実際に上記のコードを実行する場合は、A列の適当な位置に「ここだよ!」を入力してください。
その後、上記のコードを実行すると「ここだよ!」が入ってるセルの位置をメッセージボックスで表示します。


このFor Eachは理解するまでが難しいと思いますが、For Eachを使いこなせるようになる事でVBAの動作の幅が一気に広がりますので、頑張って覚えてくださいね。

練習問題


では最後に練習問題、と言いたいところですが、今回は内容が難しいので上記の解説を少し応用して、「A列をB列に変えてみる」や「列ではなく、行で試してみる」などして徐々に感覚を掴んで欲しいと思います。

因みに、ここまでの3種類のステートメントをマスター出来た方へお知らせです。
実はたった3種類のステートメントしかマスターしてないのに
InternetExplorerの自動操作は出来てしまうんです。
もちろん他の
ステートメントもマスターする事で操作の幅はもっと広がりますが、まずはVBAを楽しいものとして捉えてもらう為にも次回はちょっとしたマクロを作ってみたいと思います。
コピペではなく、自分で打ちながら指で覚えてくださいね。

変数のデータ型

変数宣言【Dim】にもデータ型の表は記載してますが、そのデータ型の説明という事なので、この記事にもデータ型の表を記載しておきますね。

データ型名前消費メモリ格納できるもの
Integer整数型2byte-32,768~32,767まで
Long長整数型4byte-2,147,483,648~2,147,483,647まで
Single単精度浮動小数点数型4byte-3.402823E38~
-1.401298E-45(負の値)
1.401298E-45~
3.402823E38(正の値)
Double倍精度浮動小数点数型8byte-1.79769313486232E308~
-4.94065645841247E-324(負の値)
4.94065645841247E-324~
1.79769313486232E308(正の値)
Currency通貨型8byte-922,337,203,685,477.5808~
922,337,203,685,477.5807
String文字列型2byte指定した文字列
Date日付型8byte日付と時間
Objectオブジェクト型4byteオブジェクト
Variantバリアント型16byteほぼ何でも
Booleanブール型2byteTrueまたはFalse

では上記の表のデータ型についての説明に入ります。

Integer、Long


まず【 Integer と Long 】についてです。
Integerは難しく考える事はなく、単純に整数を入れることができる枠ということになります。
ただし、-32,768~32,767という数字を超えてしまう場合は使えません。
これからマクロを組む時、例えばA1のセルからA100のセルまで1から数字を入れていくとします。
その時繰り返す数は100回なので32,767を超えていませんのでLongより消費メモリが軽いIntegerを使うと最適ですよね?
でも金額の計算をしてる場合、32,767円は簡単に超える可能性が高いと思います。
もし32,767を超えた場合、Integerの箱から溢れてしまいますので、そういう時に使うのがLongになります。
このLongの場合、2,147,483,647まで使えますので20億を超えない限り使えなくなることはありません。
なので莫大な数字を扱う場合以外はInteger、莫大な数字を扱う場合はLongにするといいでしょう。

Single、Double


次に【 Single と Double 】についてです。
このSingleとDoubleに関しては、パソコンの専門的な知識が必要になりますので詳しい説明は省きます。
簡単に説明するとSingleは整数と小数合わせて7桁、Doubleは整数と小数合わせて16桁まで扱えます。
また、小数点を扱う場合、SingleやDoubleを使わないといけないということはなく、むしろSingleやDoubleを使った方がごくわずかな誤差などが出やすいため、計算などはStringでもできますのでそちらをお勧めします。

Currency


次に【 Currency 】についてです。
こちらもSingleやDoubleと同じで使用する機会が少ないものになり、同じようにパソコンの専門的な知識が必要になりますので詳しい説明を省きます。
Single、Double、Currencyは全て2進数や10進数などが絡んできますので、詳しく知りたい方はネットで調べてみてくださいね。

String


次の【 String 】は一番使う事になってくると思います。
このString型は数字でも記号でも平仮名やカタカナ、漢字まで文字なら何でも入れてくれるのです。
記載方法はダブルクォーテーションで囲みます。
ただし、記号を使う際にダブルクォーテーションを使いたい場合はダブルクォーテーションを2重にします。
例1)ダブルクォーテーションを使わない場合
変数名 = "このサイトわかりやすい?笑" → このサイトわかりやすい?笑
例2)ダブルクォーテーションを使う場合
変数名 = ""ここのサイトわかりやすい?笑"" → "このサイトわかりやすい?笑"

Date


次に【 Date 】についてです。
こちらも人によっては使うことも多いかと思いますが、個人的にはFormatなどの関数を利用することのほうが多いです。
こちらは日付と時間の表記に使うものになります。
日付は西暦100年1月1日 ~ 西暦9999年12月31日まで
時間は0:00 ~ 23:59までを扱う事ができます。

Object


次に【 Object 】についてです。
このObjectはこのサイトのテーマでもあるInternetExplorer(IE)の自動操作では特に一番重要になります。
なのでIEの自動操作がしてみたい方はよく覚えておいてくださいね。
もちろん、Excelの中でも重要になるので出来るだけ覚えておいてください。
Objectとは簡単に言うとパーツです。
例えばExcelのA1とかA2とかのセルもObjectですし、このサイトにある表や今このサイトを見てくださってるブラウザ(IEだったりChromeだったり)もObjectです。
サイトを見ていて文字を打てる部分、検索などのボタンなどもObjectです。
つまり何かを動かそうと思ったらパソコンに「○○というObjectを動かして」と指示をしないといけないのです。
これからVBAを組む中でセルの指定だったりIEを選んだりする際に意識していくとわかりやすいと思います。

Varinat


次に【 Variant 】についてです。
これは特に何も考えることはないです。
単純にVariantを指定してあげたら後はパソコンが自動で適切な型になってくれるので、もしどの型に入れていいかわからない時はVariantを使うといいと思います。
ただし、消費メモリが一番大きいので処理速度は一番遅いです。
なので型がわかる時には出来るだけ適切な型を使ってあげましょう。

Boolean


最後に【 Boolean 】についてです。
これはIfなどのステートメントを使いだすと使用する機会があるかと思いますが、BooleanはTrueもしくはFalseを格納します。
Trueとは日本語では「真」と言い、正しいという意味です。
Falseとは日本語では「偽」と言い、間違っている時です。
この辺りについてはIfステートメントの時にわかるようになると思います。
Booleanについては自分がTrueの値が欲しかった時やFalseの値が欲しかった時に使います。

繰り返し【For】

変数の宣言まで出来たら次は繰り返しの処理を覚えましょう。
以前VBAとは?の記事で実行したセルの色付けのコードを見てください。
For ~ To ~とありますよね?
この時、A1からD1まで繰り返し、A2からD2まで繰り返し・・・・A14からD14まで繰り返しという感じで、横に4回同じ処理を繰り返した後、下に1行下がって、また横に4回同じ処理を繰り返すという動作になっています。
このように繰り返しの作業をする事で手動で1つ1つ進めるより格段に処理が早くなるのです。

For~To~Step~Next

例)For s = 1 To 100 Step 5
    処理内容
  Next

まず【For s = 1】については「これから繰り返しの処理を始めますよ」の合図です。
s = 1の部分に関してはsは変数なのでDimで宣言した変数名を使用し、次の1はスタート位置です。

次の【To 100】については「ここまで繰り返しますよ」の終着点を決める事になります。
上記の例の場合、sの変数に入ってる「1番からToの後の100番目まで処理しますよ」ということになります。

次に【Step 5】については「何個飛ばしで進めますよ」の意味になります。
上記の例では「1番から100番まで5個飛ばしで進めていきますよ」の意味になります。
1番が終わったら5個飛ばして6番、6番が終わったら5個飛ばして11番・・・・となり96番が終わると101番になり、100番を超えたので終了という事で、合計20回の処理になります。

最後に【Next】をつけて「ForからNextまでの間の処理が終わったらForに戻りますよ」の意味になります。
これはForとセットになってるので、Forが付いたら最後にNextと覚えておいてください。

このように繰り返しのステートメントをマスターする事で、今まで同じ処理を毎日繰り返していたのがマクロによって数秒で終わるようになるのです。

練習問題

最後に練習問題です。
下にある画像の様にA1のセルに1をA3のセルに3を、というように19行目まで1つ飛ばしでセルの行数の数字が入るようにVBAを組んでみてください。
上の文章にはヒントだらけなのでわからなければ読み直してみてくださいね。


※答えは次回の記事に載せておきます。

変数の代入

変数宣言【Dim】で変数を宣言したら次にすることは変数の代入です。
変数に値を代入するには【=】を使用し、オブジェクトを代入する場合には【Set~=】を使用します。

例1)Dim sample As String
       sample = "値の代入"
例2)Dim sample As Object
     Set sample = Range("A1")

では上記の例1から説明します。
例1ではsampleというString型の変数を用意し、その変数に「値の代入」という文字列を代入してます。
VBAでは=は等号だけではなく、代入の場合も使うのです。

次に例2ではsampleというObject型の変数を用意し、その変数に「A1のセル」を代入しています。
オブジェクト型の場合、変数の代入には=だけではなくSetも必要になるので注意してください。

また次回以降に出てくるForやForEachのステートメントに変数を使う場合は変数の代入方法が異なりますので、これからの記事ごとの変数の宣言にも注意しながら勉強してくださいね。

VBAの書き始め【Sub】

まず前提として、VBAを実行した際、かならず上から順番に実行していくようになっています。
その為、処理の順番を間違えると結果が変わってきてしまうので注意が必要です。

ではこれからVBAを書いていく際にまず大まかなイメージとしては一つの大きい棚を用意します。
その中に次回以降出てくる変数やステートメントなどの引き出しを作ってあげる事で、VBAは一番上の引き出しから順番に引き出しを開けて中身を処理したら次の引き出しにという感じで処理をしてくれるようになるのです。

ではまずVBAの書き始めに必ず入るプロシージャというものを説明します。
プロシージャは大きく2つに分けられます。
1つ目はタイトルにもある【Subプロシージャ】、2つ目は【Functionプロシージャ】です。
他にも【Eventプロシージャ】などもありますが、まずは【Subプロシージャ】を覚えましょう。

Subプロシージャはこれから自分が作成するマクロの名前にもなります。
この名前は自分がマクロを実行する際にわかりやすい名前をつけましょう。
ただし、数字から始まる場合やアンダーバー以外の記号は使うことは出来ませんが、途中や最後に数字を入れることや漢字や平仮名、カタカナは使うことが出来ます。

例)Sub Sample()
    ここに処理を記載
      End Sub

という形でSubで始まり、例ではSampleと書いてある部分に好きな名前をつけ、最後にEnd Subで終わるという流れになります。
()は変数の受け渡しの際に利用しますが、変数の受け渡しに関しては使わない場合もありますので今は空白で大丈夫です。
また変数に関しては変数宣言【Dim】に記載していますのでそこまで頑張って進んでいきましょうね。

Functionプロシージャに関しては次回のVBAの書き始め【Function】で説明します。
なので、今はSubプロシージャというもので棚を作るというところまで覚えて次の記事に進んでください。

2017年3月21日火曜日

VBAの演算子

代入演算子


演算子 意味 使用例
= 左辺に右辺を代入する a = 1

算術演算子


演算子 意味 使用例
+ +の左右の値を足す 1 + 1 = 2
- -の左右の値を引く 1 - 1 = 0
* *の左右の値を掛ける 1 * 1 = 1
/ /の左右の値を割る 7 / 2 = 3.5
¥ ¥の左右の値を割り、商を返す 7 ¥ 2 = 3
Mod Modの左右の値を割り、余りを返す 7 Mod 2 = 1
^ ^の左辺を右辺のべき乗する 2 ^ 3 = 8

比較演算子


演算子 意味 使用例
= 等号 1 + 1 = 2
<> 不等号 2 + 2 <> 2
< 左辺より右辺の方が大きい 1 < 2
> 左辺より右辺の方が小さい 2 > 1
<= 右辺は左辺以上 1 <= 2
>= 右辺は左辺以下 2 >= 1
Is Isの左右のオブジェクトが同じオブジェクトか比較 Range("A1") Is Cells(1, 1)
Like 左辺の文字列と右辺の文字パターンを比較 "あいうえお" Like "あいうえお"

Likeの文字パターン


文字パターン 意味 True(真)になる値
* 文字列(ワイルドカード) Like あいう* = あいうえ、あいうえお、あいうえおか
? 1文字 Like あいう? = あいうえ、あいうお、あいうか
# 数字 Like #1 = 01,11,21・・・

文字列連結演算子


演算子 意味 使用例
& &の左右の文字列を連結させる あいう & えお = あいうえお
+ +の左右の文字列を連結させる あいう & えお = あいうえお

論理演算子


演算子 意味 True(真)になる条件
And 左辺、右辺ともにTrue(真)の時 1 < 2 And 2 < 3
Not 条件がFalse(偽)の時 Not 1 > 2
Or Orの左辺、右辺どちらか1つでもTrue(真)の時 1 < 2 Or 2 < 1
1 < 2 Or 2 < 3
Xor Xorの左辺、右辺どちらかがTrue(真)、どちらかがFalse(偽)の時 1 < 2 Xor 2 < 1

繰り返し【Do Until】

今回の記事では、前回の【Do While】と似たもので【Do Until】を紹介したいと思います。

前回の答え


が、まずは前回の練習問題の答えから

練習問題
1.ExcelのA列、どこでもいいので好きな文字を入れてください。
2.自分でDoを使ってA列に入れた文字の上まで何かの文字を入れて繰り返しをしてみてください。


という問題でしたね。

正解のコードはこちらです。
Sub DoWhile()
Dim s As Integer
s = 1
Do While Cells(s, 1).Value <> "↑ここまで↑"
    Cells(s, 1).Value = "まだ?"
    s = s + 1
Loop
End Sub
では解説していきます。

【Dim s As Integer】
【s = 1 】
ここは何度も説明しているのでわかりますよね?
わからない方は変数宣言【Dim】を確認してください。

【Do While Cells(s, 1).Value <> "↑ここまで↑"】
ここがポイントです。
s行目、1列目のセルの値が「↑ここまで↑」ではない間、繰り返しますよ
という事になります。

もしValue <> "↑ここまで↑"をValue = "↑ここまで↑"にしてしまった場合、セルの値が「↑ここまで↑」の間、処理をするということになりますので、「特定の文字が入ったセルまで、何か文字を入れてください」という今回の問題では不正解になります。

【s = s + 1】
これはセルの行数を変更する為、変数の値を変えてあげるという処理になります。

今回の答えはA列に「↑ここまで↑」以外の文字があっても、その文字まで繰り返す、という意味でこういう答えにしましたが、単純に「空白のセルの間」という処理にする場合は下記の様にコードを変えてあげることで処理が出来ます。
Sub DoWhile()
Dim s As Integer
s = 1
Do While Cells(s, 1).Value = ""
    Cells(s, 1).Value = "まだ?"
    s = s + 1
Loop
End Sub
この様に、赤文字の部分を変更してあげる事で「空白の間、処理を実行します」という内容に変わるので、文字が入っていたら繰り返しが終了します。

ここまでは大丈夫でしょうか?
VBAを始めたばかりでは難しいとは思いますが、何度も失敗しながら練習して、マスターしてくださいね。

Do Until


では本題の【Do Until】の解説に入りたいと思います。
まずはコードの例を見てください。

例)
Sub DoUntil()
Dim s As Integer
s = 1
Do Until s > 10
    Cells(s, 1).Value = s
    s = s + 1
Loop
End Sub

【Dim s As Integer】
【s = 1】
ここは上記でも説明したように、何度も説明しているので、変数宣言【Dim】をご覧ください。

【Do Until s > 10】
ここは「sに代入されてる値が10より大きくなるまで繰り返す」という処理になります。
Untilは、○○になるまで処理を実行というステートメントになります。

【Cells(s, 1).Value = s】 
【s = s + 1】
 こちらは前回の繰り返し【Do While】と同じで「s行目、1列目のセルにsに代入された値を入れる」
「sの値を今のsの値+1する」という処理になります。

最後に【Loop】 で閉じて、【Do Until】に戻って処理を実行するかの条件を確認します。

前回のWhileと今回のUntilの違いですが、Whileは前回の練習問題の解説でも説明したように、「〇〇の間、処理を実行します」 という意味になります。
ですが、Untilは「〇〇になるまで、処理を実行します」という意味になるのです。

つまり、【Do Until s > 10】と【Do While s <= 10】は同じ処理を実行します。Untilの場合、「sが10より大きくなるまで=sが11になったら終了」
Whileの場合、「sが10までの間=sが11になったら終了」
という意味になります。

なのでどちらのステートメントを使っても、結果は同じになります。
ただ、例えば「○○の範囲を繰り返し」という時にはWhileを「○○になるまでは繰り返し」という時にはUntilを、という様に自分なりの使い分けを考えてみるのもいいかもしれませんね。

また、前回の繰り返し【Do While】でも説明したようにDoの後にUntilを付けた場合、処理実行前に条件を確認します。
Loopの後にUntilを付けた場合、処理実行後に条件を確認します。

最後に


最後におまけです。
前回の練習問題の「特定の文字が入ったセルまで、何か文字を入れてください」という問題を今回解説したUntilを使用して解答した場合、どういうコードになるかを解説します。
Sub 解答()
Dim s As Integer
s = 1
Do Until Cells(s, 1).Value = "↑ここまで↑"
    Cells(s, 1).Value = "まだ?"
    s = s + 1
Loop
End Sub
この様に、繰り返しの条件が【Do Until Cells(s, 1).Value = "↑ここまで↑"】となります。
上でも解説している様に、Untilの場合、「○○になるまで」という意味なので、【s行目、1列目のセルの値が「↑ここまで↑」になるまで繰り返し】という処理をします。

2017年3月17日金曜日

繰り返し【Do While】

VBAでは繰り返しのステートメントは大きく分けて3つほどあります。
今まではForとFor Eachを紹介しました。

Do While


では今回はDo Whileを紹介していきたいと思います。

では早速簡単な例を出してみましょう。

例)Dim s As Integer
   s = 1
   Do While s < 11
       Cells(s, 1).Value = s
       s = s + 1
   Loop

【Dim s As Integer】
【s = 1】
この二つはもうわかりますよね?
sというInteger型の変数に1を代入しています。

【Do While s < 11】
このDoが繰り返しの始まりになります。
次のWhileは繰り返しを終了させる条件を記載する場所になります。
このコードでは【s < 11】が繰り返しの終了条件になり、この繰り返しの条件がTrue(真)になった時点で繰り返しが終了します。
なのでsの値が11になった時点で、Whileの条件がTrue(真)になるので、繰り返しが終了します。
つまり、繰り返しの回数は10回という事になります。

【Cells(s, 1).Value = s】 
これも今まで何度かやりましたね。
「s行目、1列目のセルにsに代入されている値を入れる」という処理です。

【s = s + 1】
これが意外と抜けやすいところです。
今までのForやFor Eachでは「ここから、ここまで 」と繰り返しの範囲を決めていましたよね?
例えばFor s = 1 To 10とすると、「自動でsの値が+1ずつしていき、10になると終わる」というようになっていました。

ですが、Doの場合、Whileの後の条件がTrue(真)になるまで繰り返します。
ということはDoではsの値を+1するという事はしないのです。その為、自分で変数sに、今変数sに入ってる値+1しないとsはいつまで経っても1のままなので終わることが出来ません。
なので、【s = s + 1】が必要になります。

【Loop】
繰り返しの上の枠が【Do】であるように【Loop】は繰り返しの下の枠になります。
つまりDo~Loopまでの範囲が繰り返しの対象になりますので、「Doに戻ってください」の意味になります。

この【Do】のコードを簡単にまとめると「s行、1列目のセルにsに代入されてる値を、sが11になるまで繰り返す」と言う事になります。

またWhileに関してはDoの後、もしくはLoopの後のどちらかに記載をします。
Doの後にWhileを記載すると繰り返しに入る前に条件を確認し、Loopの後にWhileを記載すると処理が終わった後に条件を確認します。

その為、条件に合わなかった時、処理を始めたい場合はDoの後にWhileを記載します。
逆に1回目の処理を実行した後に条件に合わなければ繰り返したい時、Loopの後にWhileを記載します。

このDo While~LoopやDo~Loop Whileを上手く利用する事で、特定のセルまで繰り返したり、文字列などからセルを検索したりも出来るようになります。
また、IEの読み込み待ちにも、このDo Whileが使われています。

練習問題


では最後に練習問題
1.ExcelのA列、どこでもいいので好きな文字を入れてください。
2.自分でDoを使ってA列に入れた文字の上まで何かの文字を入れて繰り返しをしてみてください。


コード実行後はこのようになれば正解です。
また、実際のコードは次回の繰り返し【Do Until】に記載します。

2017年3月14日火曜日

セルの範囲選択と可変式選択

前回セルやワークシートの指定の応用として、範囲指定をする方法を説明したいと思います。

まずは例題としてA1からC3までの範囲を選択するVBAを紹介します。

例)Range("A1:C3").Select

これはExcelの関数を使える人ならすぐにわかりますよね?
単純に「:」を間に入れてあげることで範囲を選択します。
その後の「.Select」を入力する事で、「その範囲を選択してください」ということになります。

では行や列を選択する場合はどうするかというと

例1)Rows(1).Select
例2)Columns(1).Select

まずは例1の【Rows】から説明するとRowsとは行を意味しますので、括弧の中にある1番目の行という事で1行目を選択します。

次に例2の【Columns】ですがこちらは列を意味しますので、括弧の中にある1番目の列という事でA列を選択します。

では少し難しくして可変式の範囲選択をする方法を紹介します。
が、その前に2つのポイントを覚えないといけません。

まず覚えて欲しいのが【Row】と【Column】です。
Rowは行数、Columnは列数を表します。
この時、先程のRowsやColumnsの様にsは付いていない事に注意してください。

2つ目に【End(xl○○)】です。
この○○にはDownやUp、ToRightやToLeftが入ります。
意味は○○の方向の最後を意味します。
ちなみに最後と言っても入力があるセルの最後を取得しますので、もし空白のセルの最後を取得したらExcelの一番最後の数字を取得してしまうので注意してください。

では上記の2つのポイントをRangeと組み合わせて文字が入ってる一番下の行まで範囲選択するコードを書くと
Cells(Range("A1").End(xlDown).Row, 1).Select
となります。

例えばA1からA20のセルまで何かの文字が入っていた時、上記のコードではA1からA20のセルを選択します。
この「.End(xlDown).Row」は、後ほど解説している繰り返し【For】と組み合わせる事で「入力のあるセルの数だけ繰り返す」という使い方も出来るようになるので覚えておいた方がいいかと思います。

では最後にRangeの中にCellsを入れた範囲選択を紹介します。

例)Range(Cells(1, 1), Cells(3, 3)).Select

上記の例だとA1からC3の範囲を選択します。
Rangeの中にCells(1, 1)=A1のセルとCells(3, 3)=C3のセルを「,」で区切る事でその範囲を指します。
最後に「.Select」をつけることで範囲選択をするという事になります。

ただ、この方法を使うなら1番目に紹介した【Range("A1:C3")】の方が簡単なのであまり使うことはないと思いますが、稀に繰り返し【For】等を使用する時にセルの選択に変数を使用する場合があり、その際に活用する事があるので、また使う時があればこのサイトへ来て頂けたらと思います。

IE操作【表の取り出し】

ここまではVBAを使ったIE上のユーザーフォームの自動操作を説明してきました。
 今回はIE上にある表のデータをExcelに抜き出してくるというマクロを解説していきます。

ではサンプルページの送信ボタンの下にある表をExcelに抜き出していきたいと思います。
表の取り出し用マクロのコードは表の取り出し【コード】に記載、HTMLはIE操作用テストページ【HTML】に記載しています。
表のHTML
<table border="1px" id="list">
  <tbody>
    <tr>
      <th>種類</th>
      <th>原価</th>
      <th>販売額</th>
    </tr>
    <tr>
      <th>軽油</th>
      <th align="right">80円</th>
      <th align="right">100円</th>
    </tr>
    <tr>
      <th>レギュラー</th>
      <th align="right">100円</th>
      <th align="right">120円</th>
    </tr>
    <tr>
      <th>ハイオク</th>
      <th align="right">120円</th>
      <th align="right">140円</th>
    </tr>
  </tbody>
</table>
VBAコード
Sub 表の取り出し()
Dim objIE As Object
Dim tbl As Object
Dim cel As Object
Dim x As Integer
Dim y As Integer
Dim snam As String

'新しいシートを作成し、名前を変更する
Worksheets.Add
snam = ActiveSheet.Name

'InternetExplorerをobjIEに代入し、IEのプロセスを起動
Set objIE = CreateObject("InternetExplorer.Application")
    
    'IEを可視化するか = はい
    objIE.Visible = True
    
    'IEのリンク先URLはB1のセルのURL
    objIE.Navigate Worksheets("情報").Range("B1").Value
    
    'IEの表示待ち
    wait objIE
    
    'objIEのHTMLの中からtableのタグをobjに代入しながら確認
    For Each tbl In objIE.Document.GetElementsByTagName("table")
        
        'objに代入されたtableタグのIDがlistの場合
        If tbl.ID = "list" Then
            
                'tblに代入されているtableタグにあるセルをExcelに移し変える
                
                '変数yに0を代入、tblに代入されているtableの行数まで繰り返す
                For y = 0 To tbl.Rows.Length - 1
                    '変数xに1を代入、tblに代入されているtableの列数まで繰り返す
                    For x = 0 To tbl.Rows(y).Cells.Length - 1
                        'Excelのx列、y行の位置にtableタグのx+1列、y+1行のセルの値を入れる
                        Worksheets(snam).Cells(y + 1, x + 1).Value = tbl.Rows(y).Cells(x).InnerText
                        '変数aの値をプラス1することで次のセルに進む
                    Next
                Next
        End If
    Next
    
    '終了のメッセージボックスを表示
    MsgBox "終了"
    
    'objIEに代入したInternetExplorerを閉じる
    objIE.Quit
    
    'objIEを空にする
    Set objIE = Nothing

End Sub

Sub wait(objIE As Object)
'objIEに代入されたInternetExplorerがビジー状態、もしくは読み込み待ちの間、処理を待つ
Do While objIE.Busy Or objIE.ReadyState < 4
    DoEvents
Loop
End Sub

HTMLの基礎


まず、HTMLの基礎として、tableタグで枠を作ります。
次にtbodyタグで「ここが tableの中身ですよ」と教えてあげます。
tbodyの中にtrタグ=行、thタグとtdタグ=セルを入れることで表が出来上がります。

マクロではtrタグやthタグとtdタグで出来上がったtableタグの表を、Excelのセルと同じような表として認識することが出来ます。
その為、tableタグを取得し、CellsやRowsなどでセルの位置を指定することが出来るのです。

ワークシートの作成~シート名の取得


では実際のコードの解説に入りたいと思います。
※VBAのコードより、変数の宣言については、過去の記事でも多数説明している為、省略します。

【Worksheets.Add】
上記のWorksheets.Addについては「Worksheetを加えてください」の意味になります。つまり、新しいシートを作成します。

【snam = ActiveSheets.Name】
次にsnamの変数にアクティブになっているシート=先程新しく作成したシートの名前を代入します。

IEの起動~状態~サイトへのアクセス~読み込み待ち


【Set objIE = CreateObject("InternetExplorer.Application")】
 こちらはIE操作【IE起動~読み込み】でも説明したようにobjIEというオブジェクト変数にInternetExplorerを代入してます。

【objIE.Visible = True】
次のVisibleは可視化なので、Trueで表示、Falseで非表示でIEを起動します。

【objIE.Navigate Worksheets("情報").Range("B1").Value】
最後にNavigateでB1のセルの値に入っているURLにアクセスします。

【wait objIE】
上記でIEの読み込み待ちをします。

ここまでは前回までの記事のおさらいのような内容なので大丈夫ですかね?
次から少しずつ変わっていきます。

表の取り出し


【For Each tbl In objIE.Document.GetElementsByTagName("table")】
上記でtableタグをtblの変数に代入しながら探します。

【If tbl.ID = "list" Then】
tblに代入されたtableタグのIDがlistの時、次の処理を実行します。

【For y = 0 To tbl.Rows.Length - 1】
変数yの値の0からtblに代入されたtableタグの表の行数まで繰り返します。
※Rows.Lengthで 行数を取得、その後に付いてる-1は、VBAではExcelの行数や列数は1から始まりますが、IE上の表やタグの数などは0から始まります。
その為、0からスタートし、最終行-1まで繰り返すという表記になります。

【For x = 0 To tbl.Rows(y).Cells.Length - 1】
変数xの値の0からtblに代入されたtableタグのy行のセルの数だけ繰り返します。
※こちらもIEの表のセルなので-1を忘れないようにしてください。

【Worksheets(snam).Cells(y + 1, x + 1).Value = tbl.Rows(y).Cells(x).InnerText】
上記が少し難しいのですが、まず、Worksheets(snam)で最初にsnamの変数に代入した新しいシートの名前のワークシートを指定し、Cells(y + 1, x + 1).Valueで、新しいシートのxとyの値+1のセルの位置に入力します。
入力する内容はtblに代入されたtableタグのy行目、左からx番目のセルの文字列です。

ここが少しわかりにくいと思いますが、コードの色分けの様に「xとyを使い、同じセルの位置に表を取り出すように」ということを意識しながら実行してみるとわかると思います。

終了のメッセージ~オブジェクトの解放


最後に前回と同様に下記3つのコードを実行し、終了のメッセージを出した後、IEを閉じ、IEの解放を行ないます。
【MsgBox "終了"】
【objIE.Quit】
【Set objIE = Nothing】

1つの記事にまとめての解説なので見づらかったりするかと思うのですが、IEの基本操作として、「For Eachでタグを選択し、Ifで操作したいタグなら中身を実行する」ということを忘れなければ、操作は出来ると思います。
後は発想力を使って自分なりでいいのでコーディングしてみてください。

表の取り出し【コード】

Sub 表の取り出し()
Dim objIE As Object
Dim tbl As Object
Dim cel As Object
Dim x As Integer
Dim y As Integer
Dim a As Integer
Dim snam As String

'新しいシートを作成し、名前を変更する
Worksheets.Add
snam = ActiveSheet.Name

'InternetExplorerをobjIEに代入し、IEのプロセスを起動
Set objIE = CreateObject("InternetExplorer.Application")
    
    'IEを可視化するか = はい
    objIE.Visible = True
    
    'IEのリンク先URLはB1のセルのURL
    objIE.Navigate Worksheets("情報").Range("B1").Value
    
    'IEの表示待ち
    wait objIE
    
    'objIEのHTMLの中からtableのタグをtblに代入しながら確認
    For Each tbl In objIE.Document.GetElementsByTagName("table")
        
        'tblに代入されたtableタグのIDがlistの場合
        If tbl.ID = "list" Then
            
                'tblに代入されているtableタグにあるセルをExcelに移し変える
                
                '変数yに0を代入、tblに代入されているtableの行数まで繰り返す
                For y = 0 To tbl.Rows.Length - 1
                    '変数xに1を代入、tblに代入されているtableの列数まで繰り返す
                    For x = 0 To tbl.Rows(y).Cells.Length - 1
                        'Excelのx+1列、y+1行の位置にtableタグのx列、y行のセルの値を入れる
                        Worksheets(snam).Cells(y + 1, x + 1).Value = tbl.Rows(y).Cells,(x).InnerText
                    Next
                Next
        End If
    Next
    
    '終了のメッセージボックスを表示
    MsgBox "終了"
    
    'objIEに代入したInternetExplorerを閉じる
    objIE.Quit
    
    'objIEを空にする
    Set objIE = Nothing

End Sub

Sub wait(objIE As Object)
'objIEに代入されたInternetExplorerがビジー状態、もしくは読み込み待ちの間、処理を待つ
Do While objIE.Busy Or objIE.ReadyState < 4
    DoEvents
Loop
End Sub

IE操作用テストページ【HTML】

IE操作用テストページのHTML
<script type="text/javascript">
  function inf(frm){
    var nam = frm.h_name.value;
    var pas = frm.birthday.value;
    var sex = frm.sex.value;
      alert("ハンドルネーム:" + nam + "\n" + "パスワード:" + pas + "\n" + "性別:" + sex);
};
</script>

<form id="frm" onsubmit="return inf()">
  <table border="1px" id="main_table">
    <tbody>
      <tr>
        <th>ハンドルネーム</th>
        <td><input id="h_name" type="text" /></td>
      </tr>
      <tr>
        <th>生年月日</th>
        <td><input id="birthday" type="password" /></td>
      </tr>
      <tr>
        <th>性別</th>
      <td><input name="sex" type="radio" value="男性" /> 男性 
        <input name="sex" type="radio" value="女性" /> 女性</td>
      </tr>
      <tr>
        <th>使用したことのあるOS</th>
          <td><input name="os" type="checkbox" value="Windows" /> Windows 
             <input name="os" type="checkbox" value="Mac" /> Mac OSX 
             <input name="os" type="checkbox" value="Linux" /> Linux</td>
        </tr>
      <tr>
        <th>Excelのバージョン</th>
        <td><select id="version">
            <option value="2016">Excel2016</option>
            <option value="2013">Excel2013</option>
            <option value="2010">Excel2010</option>
            <option value="2007">Excel2007</option>
           </select></td>
      </tr>
      <tr>
        <th>メモ欄</th>
        <td><textarea cols="40" id="note" rows="3"></textarea></td>
      </tr>
    </tbody>
  </table>
  <br />
  <input id="date" onclick="inf(frm)" type="submit" value=" 送信 " />
</form>
<br />
<table border="1px" id="list">
  <tbody>
    <tr>
      <th>種類</th>
      <th>原価</th>
      <th>販売額</th>
    </tr>
    <tr>
      <th>軽油</th>
      <th align="right">80円</th>
      <th align="right">100円</th>
    </tr>
    <tr>
      <th>レギュラー</th>
      <th align="right">100円</th>
      <th align="right">120円</th>
    </tr>
    <tr>
      <th>ハイオク</th>
      <th align="right">120円</th>
      <th align="right">140円</th>
    </tr>
  </tbody>
</table>

2017年3月13日月曜日

IEの自動操作

まずはVBAを使ったIEの自動操作でどういうことが出来るのかを理解して頂く為に、こちらの記事では解説はせずに実際に私の方で作成したマクロを実行だけ試して頂きたいと思います。

IE自動操作用Excel(マクロ入り)

Chromeより実行する際、別タブが開き文字化けするという方は、右クリックから「名前をつけてリンク先を保存」からダウンロードし、実行してください。

上記のExcelファイルを開き、2,3行目を入力し、4,5,6行目の項目はリストから選択してください。
そこまでできたら「IE自動操作の実行」というボタンを押してみてください。

ボタンを押したら自動でIEが開き、こちらのブログに作成したテスト用のページに繋がります。
ページが表示されたら自分で入力した2~7行目の内容が反映し、送信ボタンが自動で押され、入力した内容のアラートがIE上に表示されると思います。
※実際には何も情報は送信しておりませんので安心してください。

次に「表の取り出し」のボタンを押してみてください。
同じテスト用のページに繋がり、先程の入力ボックスの下の表がExcel上に表示されたと思います。

このようにリストの取り出しからユーザーフォームの入力まで、基本的な操作は自動ですることが出来るのです。
ただし、HTMLと違い、Javascriptに関しては読み込みの確認などが出来ないので、知識の応用で処理できる方法をその都度探す必要があります。

では次回から解説に入りますので、これからIEの自動操作が出来るように頑張りましょうね。