VBAを使用したMicrosoft Excelのルーチン自動化

すべてにご挨拶。









この投稿では、さまざまなルーチンを自動化するために、VBAとは何か、Microsoft Excel 2007/2010でVBAを使用する方法(古いバージョンの場合、インターフェイスのみが変更され、コードはほとんど同じになる)を説明します。















VBA(Visual Basic for Applications)は、多くのMicrosoft Office製品に組み込まれているVisual Basicの簡易バージョンです。 特定のドキュメントのファイルにプログラムを直接書くことができます。 さまざまなIDEをインストールする必要はありません-デバッガーを含むすべてが既にExcelにあります。









Visual Studio Tools for Officeを使用して、C#でマクロを記述し、それらを埋め込むこともできます。 FireStormに感謝します









私はすぐに言わなければならない-他の言語(C ++ / Delphi / PHP)での書き込みも可能ですが、オフィスファイルの読み取り、変更、書き込みの方法を学ぶ必要があります-ドキュメントに埋め込むことはできません。 また、MicrosoftインターフェイスはCOMを介して機能します。 すべての恐怖を理解するために、COMを使用したHello Worldを紹介します。









したがって、悲しいかな、Visual Basicを学習します。









少しの準備と問題の説明



行きましょう。 Excelを開きます。









まず、開発者パネルをリボンに追加しましょう。 フォームを構築するためのボタン、テキストフィールド、その他の要素が含まれています。

















タブが表示されました。

















ここで、VBAを研究する例について考えてみましょう。 最近、表のように見える価格表をうまく整理する必要がありました。 Googleにアクセスし、「価格表」を入力して、次のように装飾されたものをダウンロードします(広告の場合は考慮しないでください)。

















つまり、商品を組み合わせることができる少なくとも2つのグループが必要です(この場合、これらはこの順序でタイプメーカーになります)。 提案したアルゴリズムが正しく機能するように、1つのグループの商品が最初に並んでいるように商品を並べ替えます(最初にType 、次にManufacturer )。









達成したい結果は次のようになります。

















もちろん、コンピューターでのみ価格表を見る場合は、フィルターを追加できます。適切な製品を検索する方がはるかに便利です。 ただし、コーディング方法を学びたいので、タスクは非常に適切です。









コディム



最初にボタンを作成する必要があります。クリックすると、プログラムが呼び出されます。 ボタンは「開発者」パネルにあり、「挿入」ボタンに表示されます。 ボタンフォームコンポーネントが必要です。 クリックして、シートの任意の場所に置きます。 さらに、マクロ宛先ウィンドウが表示されない場合は、右クリックして「マクロの割り当て」項目を選択する必要があります。 FormatPriceと呼びましょう。 マクロ名の前に何もないことが重要です。そうしないと、ブックの名前空間ではなく、別のモジュールで作成されます。 この場合、選択したシートにすばやくアクセスすることはできません。 「新規」ボタンをクリックします。

















そして、ここではVB開発環境にいます。 また、コンテキストメニューから「ソーステキスト」/「コードの表示」コマンドを使用して呼び出すこともできます。

















スタブプロシージャのあるウィンドウを次に示します。 デプロイできます。 コードは次のようになります。









Sub FormatPrice()



End Sub












Hello Worldを書きましょう。









Sub FormatPrice()

MsgBox "Hello World!"

End Sub












そして、ボタンをクリックする(以前に選択を削除する)か、エディターから直接F5を押すことで開始します。









ここでは、おそらく、VBの構文に関する小さな教育プログラムに気を取られるはずです。 誰が知っているか、彼はこのセクションを最後まで安全にスキップできる。 Visual BasicとPascal / C / Javaの主な違いは、コマンドが分離されていないことです。 ただし、実際に1行に複数のコマンドを記述したい場合は、改行またはコロン( :)を使用します。 構文の基本的なルールを理解するために、抽象的なコードを提供します。













構文例


' .

' VBA

Sub foo(a As String , b As String )

' Exit Sub ' " "

MsgBox a + ";" + b

End Sub



' . Integer

Function LengthSqr(x As Integer , y As Integer ) As Integer

' Exit Function

LengthSqr = x * x + y * y

End Function



Sub FormatPrice()

Dim s1 As String , s2 As String

s1 = "str1"

s2 = "str2"

If s1 <> s2 Then

foo "123" , "456" '

End If



Dim res As sTRING ' VB . ,

Dim i As Integer

'

For i = 1 To 10

res = res + CStr(i) ' String

If i = 5 Then Exit For

Next i



Dim x As Double

x = Val( "1.234" ) '

x = x + 10

MsgBox x



On Error Resume Next ' -

x = 5 / 0

MsgBox x



On Error GoTo Err ' Err

x = 5 / 0

MsgBox "OK!"

GoTo ne



Err:

MsgBox "Err!"



ne:

On Error GoTo 0 '



' ,

Do While True

Exit Do



Loop 'While True

Do 'Until False

Exit Do

Loop Until False

' , , .

' Val Integer

Select Case LengthSqr(Len( "abc" ), Val( "4" ))

Case 24

MsgBox "0"

Case 25

MsgBox "1"

Case 26

MsgBox "2"

End Select



' .

' ReDim (Preserve) - . google

Dim arr(1 to 10, 5 to 6) As Integer

arr(1, 6) = 8



Dim coll As New Collection

Dim coll2 As Collection

coll.Add "item" , "key"

Set coll2 = coll ' Set

MsgBox coll2( "key" )

Set coll2 = New Collection

MsgBox coll2.Count

End Sub








熊手-1。 IDEからコードを(英語のExcelで)コピーすると、すべてのテキストが1252 Latin-1に変換されます。 したがって、ロシア語のコメントを保存する場合は、ワニをLatin-1として保存し、1251で開く必要があります。









レーキ2。 なぜなら VBでは未宣言の変数を使用できます。OptionExplicitは常にコードの先頭(すべての手順の前)に配置します。 このディレクティブは、インタープリターがそれ自体で変数を開始するのを防ぎます。









すくい3。 グローバル変数は、最初の関数/プロシージャの前でのみ宣言できます。 ローカル-プロシージャ/ファンクション内の任意の場所。









InPosMidTrimLBoundUBoundといった便利な追加機能がいくつかあります。 また、関数の操作/そのパラメーターに関するすべての質問に対する回答は、MSDNで入手できます。









これで、コードを怖がらず、自分でコンピューターサイエンスの宿題を書くのに十分であることを願っています。 投稿中に、目立たないように新しいデザインを紹介します。









私たちはExcelの下でたくさんコーディングします



このパートでは、Excelのシートで機能するもののコーディングを既に開始します。 まず、 resultという名前の別のシートを作成します(データシートはdataと呼ばれます )。 さて、おそらく、このシートの内容をクリアする必要があります。 また、データシートを「選択」して、シートを使用して配列に長い呼び出しを書き込まないようにします。









Sub FormatPrice()

Sheets( "result" ).Cells.Clear

Sheets( "data" ).Activate

End Sub












セル範囲を操作する



Excel VBAでのすべての作業は、セル範囲で行われます。 それらはRange関数によって作成され、タイプRangeのオブジェクトを返します。 彼はデータやデザインを扱うのに必要なすべてを持っています。 ところで、シートのCellsプロパティもRangeです。













範囲の


Sheets( "result" ).Activate

Dim r As Range

Set r = Range( "A1" )

r.Value = "123"

Set r = Range( "A3,A5" )

r.Font.Color = vbRed

r.Value = "456"

Set r = Range( "A6:A7" )

r.Value = "=A1+A3"








それでは、コードのアルゴリズムを理解しましょう。 したがって、2番目から始まるデータシートの各行には、興味のないデータ( ID名前 、および価格 )があり、それが属する2つのネストされたグループ( typeおよびmanufacturer )があります。 さらに、これらの行はソートされます。 新しいグループを始める前にギャップを忘れてしまいますが、それは簡単です。 私はこのようなアルゴリズムを提案します:









  1. 次の行からグループをカウントしました。
  2. すべてのグループを優先度の高い順に並べます(最初の大きなグループ)

    1. 現在のグループが一致しない場合、 AddGroup(i、name)プロシージャを呼び出します。ここで、 iはグループ番号(現在の番号から最大まで)、 nameはその名前です。 ヘッダーだけでなく、すべてのヘッダーを作成するには、いくつかの呼び出しが必要です。
  3. 必要なヘッダーをすべて描画した後、別の行を作成してデータを入力します。




作業を簡素化するために、次の削減関数を定義することをお勧めします。









Function GetCol(Col As Integer ) As String

GetCol = Chr(Asc( "A" ) + Col)

End Function



Function GetCellS(Sheet As String , Col As Integer , Row As Integer ) As Range

Set GetCellS = Sheets(Sheet).Range(GetCol(Col) + CStr(Row))

End Function



Function GetCell(Col As Integer , Row As Integer ) As Range

Set GetCell = Range(GetCol(Col) + CStr(Row))

End Function












次に、グローバル変数「現在の行」を定義します: Dim CurRow As Integer 。 手順の始めに、それは統一に等しくする必要があります。 また、変数「 データの現在の行」、現在の前の行のグループ名を持つ配列が必要です。 次に、「行の最初のセルが空でない間に」サイクルを書くことができます。













グローバル変数


Option Explicit '

Dim CurRow As Integer

Const GroupsCount As Integer = 2

Const DataCount As Integer = 3












フォーマット価格


Sub FormatPrice()

Dim I As Integer ' data

CurRow = 1

Dim Groups(1 To GroupsCount) As String

Dim PrGroups(1 To GroupsCount) As String



Sheets( "data" ).Activate

I = 2

Do While True

If GetCell(0, I).Value = "" Then Exit Do

' ...

I = I + 1

Loop

End Sub








次に、 グループ配列にデータを入力する必要があります













省略記号の代わりに


Dim I2 As Integer

For I2 = 1 To GroupsCount

Groups(I2) = GetCell(I2, I)

Next I2

' ...

For I2 = 1 To GroupsCount ' VB

PrGroups(I2) = Groups(I2)

Next I2

I = I + 1








そしてヘッダーを作成します:













前の部分の省略記号の代わりに


For I2 = 1 To GroupsCount

If Groups(I2) <> PrGroups(I2) Then

Dim I3 As Integer

For I3 = I2 To GroupsCount

AddHeader I3, Groups(I3)

Next I3

Exit For

End If

Next I2








AddHeaderプロシージャを忘れないでください。













フォーマット前価格


Sub AddHeader(Ty As Integer , Name As String )

GetCellS( "result" , 1, CurRow).Value = Name

CurRow = CurRow + 1

End Sub








次に、すべての情報を結果に転送する必要があります









For I2 = 0 To DataCount - 1

GetCellS( "result" , I2, CurRow).Value = GetCell(I2, I)

Next I2












列を幅に合わせ、 結果シートを選択して結果を表示します













FormatPriceの最後のループの後


Sheets( "Result" ).Activate

Columns.AutoFit








それだけです 最初のバージョンを楽しむことができます。

















glyいですが、それはそうです。 フォーマットを処理しましょう。 まず、 AddHeaderプロシージャを変更します。









Sub AddHeader(Ty As Integer , Name As String )

Sheets( "result" ).Range( "A" + CStr(CurRow) + ":C" + CStr(CurRow)).Merge

'

' With

With GetCellS( "result" , 0, CurRow)

.Value = Name

.Font.Italic = True

.Font.Name = "Cambria"

Select Case Ty

Case 1 '

.Font.Bold = True

.Font.Size = 16

Case 2 '

.Font.Size = 12

End Select

.HorizontalAlignment = xlCenter

End With

CurRow = CurRow + 1

End Sub












すでに良い:

















境界を描くためだけに残っています。 ここでは、すでにすべての結合されたセルを操作する必要があります。そうでない場合は、1つだけが境界線を持ちます。

















したがって、境界線スタイルを追加してコードをわずかに変更します。









Sub AddHeader(Ty As Integer , Name As String )

With Sheets( "result" ).Range( "A" + CStr(CurRow) + ":C" + CStr(CurRow))

.Merge

.Value = Name

.Font.Italic = True

.Font.Name = "Cambria"

.HorizontalAlignment = xlCenter



Select Case Ty

Case 1 '

.Font.Bold = True

.Font.Size = 16

.Borders(xlTop).Weight = xlThick

Case 2 '

.Font.Size = 12

.Borders(xlTop).Weight = xlMedium

End Select

.Borders(xlBottom).Weight = xlMedium ' : xlThick, xlMedium, xlThin, xlHairline

End With

CurRow = CurRow + 1

End Sub




















新しいグループを開始する前にパスを達成するためだけに残ります。 これは簡単です:













FormatPriceの開始時


Dim I As Integer ' data

CurRow = 0 '

Dim Groups(1 To GroupsCount) As String












見出しループで


If Groups(I2) <> PrGroups(I2) Then

CurRow = CurRow + 1

Dim I3 As Integer
















まさに彼らが望んだもの。









この記事が、VBAのExcelプログラミングに少し慣れるのに役立つことを願っています。 宿題-見出し「 ID、タイトル、価格 」を結果に追加します。 ヒント: CurRow = 0 CurRow = 1









ファイルはここ (min.us)またはここ (Dropbox) からダウンロードできます。 マクロの実行を有効にしてください。 誰かが人間のファイルホスティングを促す場合は、そこにアップロードします。









ご清聴ありがとうございました。







コメントで建設的な批判ができればうれしいです。







UPD: Dropboxとmin.usでサンプルリロードしました。







UPD2:実際には、 1つのパラメーターを使用してプロシージャを呼び出すときに、括弧を付けることができます。 または、 Call Fooコンストラクト(「bar」、1、2、3)を使用します -ここでは、ブラケットが常に必要です。








All Articles