【PR】


本広告は、一定期間更新の無いブログにのみ表示されます。
ブログ更新が行われると本広告は非表示となります。
  

Posted by TI-DA at

2009年07月31日

エクセルマクロ(VBA):帳票印刷④

朝、犬の散歩をしている時、歩道を掃除しているおじさん
とよく話しをしますが、話し声も聞こえないほどセミの鳴き声
がうるさいです。
耳をつんざくような大合唱ですが、
心なしか鳴き声がおさまってきているように感じられます。
気のせいでしょうか。ニコニコ

昨日のプログラムの説明です。

得意先コードが空白になるまで繰り返し処理をします。
空白になれば、処理終了です。
  
  DO UNTIL 得意先コード = ””
     
     その中に、得意先コードが変わるまで帳票編集をする繰り返し処理を入れる

     DO UNTIL 得意先コード = TOKUSAKI(前回参照した得意先コード)| 

        帳票編集   
     
     LOOP 
  
     得意先が変われば印刷をし、次の得意先を繰り返す。

  LOOP

このように、やっている事は至って単純ですが、
プログラムが長く難しそうにみえます。
改ページの処理等で条件が増えているだけで、
流れを整理して考えれば理解できるものです。

エクセルマクロ(VBA)は、ほんの少し勉強するだけで、
これぐらいのプログラムは作れるようになります。

私達、エンドユーザーが業務用のシステムを作るなら話は別ですが、
日常業務のちょっとした繰り返しの作業等はエクセルマクロ(VBA)
を使うと作業がグ~~ンと捗ります。

で、
今回、相談頂いた方の感想はというと
「目からウロコ」のビックリだそうです。
ボタン一つでできるなんて、
今までの時間、無駄な事をしていたとおっしゃっていました。

所要時間:データセットアップから印刷迄わすか10分。




めでたし!めでたし!  


Posted by ミール at 09:30Comments(0)VBA

2009年07月30日

エクセルマクロ:帳票編集③

最近、漫画喫茶に行くようになりました。
サラリーマン金太郎にはまってしまって癖になりそうです。

それでは、昨日の続きです。
今日はソートしたデータを順番よく参照していき帳票を作っていきます。

説明しやすようにシート名を決めておきましょう。
シート1「売上データ」、シート2「得意先売上表」にしましょう。
「売上データ」を1件目から順番よく参照し、「得意先売上表」に
編集していきます。

「売上データ」と「得意先売上表」の行を順番よく参照し
カウントしていき、「得意先売上表」に30件編集すると、
編集行を2ページ目の開始位置にしてカウントしていきます。
得意先が変わると、編集したページ分だけ印刷し
印刷した帳票のデータをクリアして新しい得意先の
データを1ページから編集していきます。

それではプログラムをみてみましょう。

Sub 得意先売上実績作成処理()

    Application.ScreenUpdating = False

   '----- 変数の定義 ----
   Dim g As Integer
    Dim gyo1 As Integer
   Dim gyo2 As Integer
    Dim kensu As Integer
   Dim page As Integer
   Dim tokuisaki As Variant


'----- ソート処理 ----

  Worksheets("売上データ").Select
  g = Range("A65536").End(xlUp).Row

 Range("A1:I" & g).Select

 Selection.Sort Key1:=Range("B2"), Order1:=xlAscending, Key2:=Range("A2") _
  , Order2:=xlAscending, Key3:=Range("D2"), Order3:=xlAscending, Header:= _
  xlYes, OrderCustom:=1, MatchCase:=False, Orientation:=xlTopToBottom, _
 SortMethod:=xlPinYin, DataOption1:=xlSortNormal, DataOption2:= _
 xlSortNormal, DataOption3:=xlSortNormal

'----- 帳票編集 ----

'--- 変数へ初期値設定
  gyo1 = 2 '売上データの行番号
  gyo2 = 4 '得意先売上表の行番号
  kensu = 1 '1ページの編集した件数
  page = 1 '編集したページ数
  tokuisaki = Range("b2") '得意先コードの比較用変数

'--- 得意先コードがスペースになると処理を終了する

   Do Until Range("b" & gyo1) = ""

  Worksheets("得意先売上").Range("b2") = Range("b" & gyo1)
   Worksheets("得意先売上").Range("c2") = Range("c" & gyo1)
   Worksheets("得意先売上").Range("f1") = Format(Range("A" & gyo1), "e")
   Worksheets("得意先売上").Range("h1") = Format(Range("A" & gyo1), "m")


  Do Until Range("b" & gyo1) <> tokuisaki

 If kensu > 30 Then
  Worksheets("得意先売上").Range("b" & gyo2 + 2) = Range("b" & gyo1)
 Worksheets("得意先売上").Range("c" & gyo2 + 2) = Range("c" & gyo1)
 Worksheets("得意先売上").Range("f" & gyo2 + 1) = Format(Range("A" & gyo1), "e")
 Worksheets("得意先売上").Range("h" & gyo2 + 1) = Format(Range("A" & gyo1), "m")

 gyo2 = gyo2 + 4
 page = page + 1
 kensu = 1
 End If

'--- 売上データを得意先売上表に編集する
  Worksheets("得意先売上").Range("a" & gyo2) = Range("a" & gyo1)
  Worksheets("得意先売上").Range("b" & gyo2) = Range("d" & gyo1)
  Worksheets("得意先売上").Range("c" & gyo2) = Range("e" & gyo1)
  Worksheets("得意先売上").Range("d" & gyo2) = Range("f" & gyo1)
 Worksheets("得意先売上").Range("e" & gyo2) = Range("g" & gyo1)
 Worksheets("得意先売上").Range("f" & gyo2) = Range("f" & gyo1) * Range("g" & gyo1)
 goukei = goukei + Range("f" & gyo1) * Range("g" & gyo1)

 kensu = kensu + 1
 gyo1 = gyo1 + 1
 gyo2 = gyo2 + 1

 Loop
' --- 得意先が変わると印刷する
 tokuisaki = Range("b" & gyo1)
 g = page * 34
  Worksheets("得意先売上").Range("f" & g) = goukei
 Worksheets("得意先売上").Select

'----- 印刷
 ActiveWindow.SelectedSheets.PrintOut From:=1, To:=page, Copies:=1, Preview:=True

'---- 得意先売上表の編集項目をクリア
  Worksheets("得意先売上").Range("a4:h33") = ""
  Worksheets("得意先売上").Range("a38:h67") = ""
  Worksheets("得意先売上").Range("a72:h101") = ""

 Worksheets("得意先売上").Range("f1") = ""
 Worksheets("得意先売上").Range("h1") = ""
 Worksheets("得意先売上").Range("b2") = ""
 Worksheets("得意先売上").Range("c2") = ""
 Worksheets("得意先売上").Range("f34") = ""

 Worksheets("得意先売上").Range("f35") = ""
 Worksheets("得意先売上").Range("h35") = ""
  Worksheets("得意先売上").Range("b36") = ""
  Worksheets("得意先売上").Range("c36") = ""
  Worksheets("得意先売上").Range("f68") = ""

 Worksheets("得意先売上").Range("f69") = ""
 Worksheets("得意先売上").Range("h69") = ""
 Worksheets("得意先売上").Range("b70") = ""
  Worksheets("得意先売上").Range("c70") = ""
  Worksheets("得意先売上").Range("f102") = ""

'---- 売上データを選択する
 Worksheets("売上データ").Select
 Worksheets("売上データ").Range("a1").Select

'--- 得意先売上表の1ページから編集するよに変数を初期値へ戻す
 page = 1
 kensu = 1
 gyo2 = 4
 goukei = 0

Loop
Application.ScreenUpdating = True
End Sub

<実行結果>



とても長いプログラムになってしまいました。
内容の説明は又明日したいと思います。

  


Posted by ミール at 09:30Comments(0)VBA

2009年07月29日

エクセルマクロ(VBA):帳票編集②(ソート処理)

今日は息子の誕生日。
少年野球をやっていて前からスパイク
が欲しいと言っていたのでプレゼントとして
買ってあげました。
早速履いて走り回っている姿に
自分も子供の頃に野球道具を揃えてもらって
感激した事をふと思い出しました。
息子よ!夢を追って汗を流せ。

それでは,昨日の続きです。

今日は、ソートの処理を考えてみます。
第1キーが得意先コード
第2キーが売上年月日
第3キーが商品コードの順で並び替えます。
そこでソートの命令文を調べて記述していたのでは時間がかかります。
こんな時、便利な機能がマクロの記録機能。

下の手順に沿ってやってみてください。簡単です。

<マクロの記録を始めます>


<ソート(並び替え)をします。:
   ソートの処理がマクロとして記録されます>


<マクロの記録を終了します>


<記録されたマクロを確認します>


ソートのマクロが出来上がりました。

<作成されたマクロです。>

Sub Macro3()
'
' Macro3 Macro

Range("A1:I100").Select
Selection.Sort Key1:=Range("B2"), Order1:=xlAscending, Key2:=Range("A2") _
, Order2:=xlAscending, Key3:=Range("D2"), Order3:=xlAscending, Header:= _
xlYes, OrderCustom:=1, MatchCase:=False, Orientation:=xlTopToBottom, _
SortMethod:=xlPinYin, DataOption1:=xlSortNormal, DataOption2:= _
xlSortNormal, DataOption3:=xlSortNormal
Range("C2").Select
End Sub

そのままではデータが増えた時に正確に動かない事があるので、
修正を加えます。
範囲指定の Range("A1:I100").Selectの部分。
データの最後尾を取得するようにしましょう。
最後尾の取得については、以前の記事で説明してますので、
参考にしてください。

「g」を変数として使います。

g = Range("A65536").End(xlUp).Row

この命令で最後尾の行番号が取得できます。
こうする事によって、データが増えてもマクロを修正せずに
使える様になります。


Sub Macro3()
'
' Macro3 Macro

g = Range("A65536").End(xlUp).Row

Range("A1:I" & g).Select

Selection.Sort Key1:=Range("B2"), Order1:=xlAscending, Key2:=Range("A2") _
, Order2:=xlAscending, Key3:=Range("D2"), Order3:=xlAscending, Header:= _
xlYes, OrderCustom:=1, MatchCase:=False, Orientation:=xlTopToBottom, _
SortMethod:=xlPinYin, DataOption1:=xlSortNormal, DataOption2:= _
xlSortNormal, DataOption3:=xlSortNormal

End Sub

これでソートのマクロは完成です。
またまた長くなりましたので続きは明日にします。  


Posted by ミール at 09:30Comments(0)VBA

2009年07月28日

エクセルマクロ(VBA):帳票編集①

新聞を読んでいて、海での事故の記事があり、
「118番」通報とかかれていました。
え・・・、「119番」の間違いじゃない?
と女房と話していたら、

小学生の息子が、自慢げに
海の事故は、「118番」だよって言ってきた。

電話帳をみると、海の事件・事故は「118番」と
大きく載っていた。

しばらく、鼻高々の日が続きそうだ。
はずかしい・・・。

では、本題。

今日は、帳票について相談があったので考えてみたいと思います。

内容は至って単純。
月初に300件程ある売上データ(エクセル)を販売課からもらい得意先別の
売上一覧表をエクセルで作っているそうです。

< サンプルデータ >

得意先毎に並び替えて、合計欄をつくり計算式を入れて
印刷するという内容。



作業自体は1時間程度なので、現在のままでもいいようですが、
マクロでやったらどうなるかなって感心を持ったようです。

        ・
        ・
さて1時間の作業がどうなるか楽しみです。

それではエクセルマクロ(VBA)での処理を考えてみましょう。

まず、販売課からもらうデータは、規則どおりに入っているもの
として、考えていきます。
規則どおりとは、例えば、日付の項目に文字が入っていたり
商品名が空白だったりという不都合なデータはないものとします。

今回の処理のポイントは、帳票をどの様に編集するかです。

処理の流れを説明します。

①販売課からもらったデータを並び替えします。
    ・得意先コード
    ・日付
    ・商品コード
  の順で並び替えます。

② 並び替えたデータを1件目から順に参照します。
  (参照するプログラムは以前にやったので参考にしてください。)
   得意先コードがスペースになれば終了とします。

③ 帳票編集
   ここは、いろんなケースが考えられますが、   
   今回は得意先1件の最大印刷ページは5ページあれば
   足りるとの事ですので、エクセルで帳票レイアウトを
   予め5ページ分作っておきます。
   (今回は練習ですので、2ページにします。)
   1ページに30取引分とします。
   
   1ページに30取引分編集したら、次のページに編集し
   得意先が変われば印刷し、帳票レイアウトをクリアします。

<帳票レイアウト>


以上の流れでプログラムを作っていきますが、
説明が長くなりそうなので続きは明日にしたいと思います。

  


Posted by ミール at 09:28Comments(0)VBA

2009年07月27日

エクセルマクロ(VBA):データの削除


先日書いたマクロの記述で、知人に教わった事があるので参考に書きます。

先日書いたマクロ、

 If  Worksheets("会員データ").Cells.Find(対象者) Is Nothing Then 
      ・
Else
  g = Worksheets("会員データ").Cells.Find(対象者).Row  
        ・
 End If


の所を一旦、オブジェクト変数を使って記述すると分かりやすいですよとの事。

オブジェクト型変数とはRangeオブジェクトやWorksheetオブジェクトなど
オブジェクトを格納する専用の変数です。

オブジェクト変数の値の代入は、数値や文字の編集のように 
変数 = 数値、文字ではなく
Set 変数 = オブジェクトとSetを使います。

また、変数の定義は
Dim obj As Rangeとなります。

オブジェクト変数を使って記述すると、

Dim obj As Range
Set obj = Worksheets("会員データ").Cells.Find (対象者)
If obj Is Nothing Then

else
  g = obj.Row  
  ・
End If

なるほど、勉強になりました。
ありがとうございました。

それでは、本題です。

今日は、削除の処理について考えてみたいと思います。


削除処理も、更新処理と同じく、対象データの行番号がわかれば
簡単に出来ます。

行番号の取得は、前回データ検索時に変数「g」に取得されています。
その「g」をそのまま使います。

対象の行番号がわかれば、その行を選択して、削除の命令を
入れると簡単に削除処理ができます。

まず、入力画面に、「削除ボタン」を追加します。



プログラムをみてみましょう。

Private Sub CommandButton4_Click()

Worksheets("会員データ").Select
Worksheets("会員データ").Range("A" & g).Activate
MsgBox (g)
Selection.EntireRow.Delete

End Sub

会員№が「000002」の「中村じゅん」さんのデータを削除します。






「中村じゅん」さんのデータが削除され行が上にシフトされました。

このプログラムも以外と簡単ですよね。

初心者の私でも理解できたので、
エクセルマクロに興味をもたれた方は、挑戦してみてはいかがでしょうか。
  


Posted by ミール at 10:51Comments(0)VBA

2009年07月24日

エクセルマクロ(VBA):データの更新②

最近、血圧が高く病院へ通っています。

今日は、定期受診の日で10時に予約をしていました。
9時40分には受付を済ませ11時には終わると思っていました。

ところが、10時30分を過ぎても呼ばれない。
確認すると、「もうすぐですからね」との返事。
しかし、11時を過ぎても呼ばれない。
またまた、確認すると「診察の長い先生ですので
もうしばらくお待ち下さい」との事。
結局、診察したのが12時。
薬をもらって帰ったのが1時。

何の為の予約かよくわからい。

またまた、血圧があがりそうだ。がーん

そんな、話はさておき・・・

本題です。


今日は、入力したデータの内容を変更するプログラムを考えてみたい
と思います。

画面に表示させた対象データを、修正して更新します。
更新ですので、単純に変更したあと登録ボタンを押してはいけません。
会員データの最後尾に登録され、二重になってしまいます。
今回は、更新ボタンを用意して表示させた対象データに上書きするように
します。





ポイントは、表示させた時の行番号を憶えておく事です。
表示用のプロシージャと更新用のプロシージャ間で変数が参照できるようにします。

変数の宣言をプロシージャの外で宣言します。

それでは、プログラムを見てみましょう。

表示用のプロシージャで「g」の変数を使っていました。
その「g」をプロシージャの外で定義します。

Dim g
Private Sub CommandButton3_Click()
Worksheets("会員データ").Select

With Worksheets("入力画面")
Worksheets("会員データ").Range("A" & g) = .Range("c4")
Worksheets("会員データ").Range("b" & g) = .Range("c5")
Worksheets("会員データ").Range("c" & g) = .Range("d5")
Worksheets("会員データ").Range("d" & g) = .Range("c6")
Worksheets("会員データ").Range("e" & g) = .Range("d6")
Worksheets("会員データ").Range("f" & g) = .Range("c7")
Worksheets("会員データ").Range("g" & g) = .Range("c8")
Worksheets("会員データ").Range("h" & g) = .Range("c10")
Worksheets("会員データ").Range("i" & g) = .Range("c11")
Worksheets("会員データ").Range("j" & g) = .Range("c12")
Worksheets("会員データ").Range("k" & g) = .Range("c14")
Worksheets("会員データ").Range("l" & g) = .Range("c15")
Worksheets("会員データ").Range("m" & g) = .Range("c16")

.Range("c4") = ClearContents
.Range("c5") = ClearContents
.Range("d5") = ClearContents
.Range("c6") = ClearContents
.Range("d6") = ClearContents
.Range("c7") = ClearContents
.Range("c8") = ClearContents
.Range("c10") = ClearContents
.Range("c11") = ClearContents
.Range("c12") = ClearContents
.Range("c14") = ClearContents
.Range("c15") = ClearContents
.Range("c16") = ClearContents

End With

Worksheets("入力画面").Select

End Sub

更新ボタンを押すと、内容が変更されました。


こんな感じで意外と簡単に、登録や変更のプログラムができます。
次回は削除の機能を考えてみたいと思います。



  


Posted by ミール at 14:00Comments(5)VBA

2009年07月23日

エクセルマクロ(VBA):データの更新①

前回、データ蓄積のプログラムを説明しましたが、
入力(蓄積)したら、データを修正・変更したり、削除したりする
処理もほしいものです。

今回はデータの修正・変更について、考えてみたいと思います。

会員コードを入力すると、対象データを入力画面に表示し、
修正した内容を登録する流れとします。

但し、会員コードの重複はないものとします。

ここで使う、検索命令はFind命令。

Worksheets("会員データ").Cells.Find(対象者)


「検索」というボタンを作り、ボタンを押すと
会員データから対象者を検索し、対象者が存在すれば、
入力画面を編集し、なければ”対象データがありません”と
メッセージボックスに表示し、入力データの項目を
クリアする処理です。


それでは、プログラムを見てみましょう。

Private Sub CommandButton2_Click()  '検索ボタンを押すと動く

Dim 対象者
対象者 = Sheets("入力画面").Range("c4")  '会員コードをセットする

With Worksheets("入力画面")

If Worksheets("会員データ").Cells.Find(対象者) Is Nothing Then  '対象データを検索する。
MsgBox "対象データがありません"
   .Range("c5") = ClearContents
  .Range("d5") = ClearContents
  .Range("c6") = ClearContents
  .Range("d6") = ClearContents
  .Range("c7") = ClearContents
  .Range("c8") = ClearContents
  .Range("c10") = ClearContents
  .Range("c11") = ClearContents
  .Range("c12") = ClearContents
  .Range("c14") = ClearContents
   .Range("c15") = ClearContents
  .Range("c16") = ClearContents
Else
  g = Worksheets("会員データ").Cells.Find(対象者).Row  '対象データの行を取得する

  .Range("c4") = Worksheets("会員データ").Range("A" & g)
  .Range("c5") = Worksheets("会員データ").Range("b" & g)
   .Range("d5") = Worksheets("会員データ").Range("c" & g)
   .Range("c6") = Worksheets("会員データ").Range("d" & g)
   .Range("d6") = Worksheets("会員データ").Range("e" & g)
   .Range("c7") = Worksheets("会員データ").Range("f" & g)
  .Range("c8") = Worksheets("会員データ").Range("g" & g)
   .Range("c10") = Worksheets("会員データ").Range("h" & g)
   .Range("c11") = Worksheets("会員データ").Range("i" & g)
   .Range("c12") = Worksheets("会員データ").Range("j" & g)
   .Range("c14") = Worksheets("会員データ").Range("k" & g)
   .Range("c15") = Worksheets("会員データ").Range("l" & g)
   .Range("c16") = Worksheets("会員データ").Range("m" & g)
End If
End With

End Sub

実行後の結果です。


対象者が存在しない場合は

となります。

次回は、修正した内容を更新するプログラムを考えてみたいと思います。  


Posted by ミール at 09:10Comments(0)VBA

2009年07月22日

エクセルマクロ(VBA):入力データの蓄積

今回は、入力データを蓄積していくプログラムを考えてみたいと思います。

シート1に会員情報の入力画面を作り、シート2に保存用のシートを作ります。

会員情報を入力し、登録ボタンを押すと、シート2に編集し、入力画面の
内容はクリアする。

内容が重複するか等のチェックは、なしとして単純に後ろへ追加していく
ものとします。



ポイントは蓄積されたデータの最後尾は何行目かを取得する事です。
最後尾がわかれば、+1した行番号に編集すればいいわけです。

A列の会員№の最後尾の行番号を取得する命令を使います。

.Range("A65536").End(xlUp).Row)

エクセルシートの最後尾(65536行目)から上方向にデータを探していきます。

ちなみに、検索された行番号が1なら、タイトル行のみなので、データは未だ入力されていない状態です。

それでは、プログラムをみてみましょう。

登録ボタンを押すと下記のプログラムが動きます。

Private Sub CommandButton1_Click()

Worksheets("会員データ").Select

g = Worksheets("会員データ").Range("A65536").End(xlUp).Row + 1

With Worksheets("入力画面")
Worksheets("会員データ").Range("A" & g) = .Range("c4")
Worksheets("会員データ").Range("b" & g) = .Range("c5")
Worksheets("会員データ").Range("c" & g) = .Range("d5")
Worksheets("会員データ").Range("d" & g) = .Range("c6")
Worksheets("会員データ").Range("e" & g) = .Range("d6")
Worksheets("会員データ").Range("f" & g) = .Range("c7")
Worksheets("会員データ").Range("g" & g) = .Range("c8")
Worksheets("会員データ").Range("h" & g) = .Range("c10")
Worksheets("会員データ").Range("i" & g) = .Range("c11")
Worksheets("会員データ").Range("j" & g) = .Range("c12")
Worksheets("会員データ").Range("k" & g) = .Range("c14")
Worksheets("会員データ").Range("l" & g) = .Range("c15")
Worksheets("会員データ").Range("m" & g) = .Range("c16")

.Range("c4") = ClearContents
.Range("c5") = ClearContents
.Range("d5") = ClearContents
.Range("c6") = ClearContents
.Range("d6") = ClearContents
.Range("c7") = ClearContents
.Range("c8") = ClearContents
.Range("c10") = ClearContents
.Range("c11") = ClearContents
.Range("c12") = ClearContents
.Range("c14") = ClearContents
.Range("c15") = ClearContents
.Range("c16") = ClearContents

End With

Worksheets("入力画面").Select

End Sub

結果は、4行目に編集されました。



そして、入力画面もクリアされました。



実際、業務で使うにはもっと条件が必要になりますが、データを蓄積するプログラムの
基本的なものなので、こんなものがあったなぁぐらいで憶えておくと便利ですよ。  


Posted by ミール at 09:10Comments(0)

2009年07月21日

エクセルマクロ(VBA):オートフィルター可視セルの操作

前回から、データを抽出するマクロについて書いていますが、
今回は、オートフィルターで抽出したデータを、
1件目から順番に参照していくマクロを考えたいと思います。

オートフィルターで画面上に抽出されたデータは、マクロ側
から見れば、単純に1行目、2行目とは認識できないようです。
あくまでも、行番号で参照するようです。



その抽出されたデータの行番号を取得する必要があります。

そこで、前回も説明した可視セルを対象とする便利な命令があります。

細かい説明は省きます・・というか、よくわかりません。
こんな命令があったぐらいでいいと思います。

それでは、
 オートフィルターで、「沖縄県」の方を抽出して、
 年齢が30歳未満の方の対象者欄(F列)へ
 〇印を編集する、マクロを作ってみます。

Sub Macro1()

  Worksheets("Sheet1").Select
  Range("A1").Select

  Selection.AutoFilter
  Selection.AutoFilter Field:=3, Criteria1:="沖縄県"

  For Each c In Worksheets("Sheet1").Columns(1).SpecialCells(xlCellTypeVisible) 

    If  c  =  "" Then                            
  Exit Sub
  End If

  If Range("e" & c.Row) < 30 Then
   Range("f" & c.Row) = "〇"
 End If

 Next c

End Sub


結果。


こんな感じでしょうか。


これができると、オ-トフィルターで抽出したデータを
別シートへコピーして、1行目から順序よく参照していく
処理は省けるかもしれませんね。
  


Posted by ミール at 10:54Comments(0)VBA

2009年07月20日

エクセルマクロ(VBA):データ抽出の基本パターン②


前回の続きですが、今日は
オートフィルターを使ったデータ抽出方法を説明したいと思います。

これも、いろいろな場面で応用として使う機会がでてきますが、
前回みたいな、プログラム的な記述ではなくて、どちらかというと
エクセルの機能を組み合わせたマクロになります。

例:データは前回と同様。


「沖縄県」の方を抽出して、シート2へ出力するという流れです。


次のような、マクロになります。
 
Sub 抽出処理2()

Worksheets("Sheet1").Select
Range("A1").Select

Selection.AutoFilter
Selection.AutoFilter Field:=3, Criteria1:="沖縄県"

Range("A1").CurrentRegion.Select

'可視セルのみをコピー
Selection.SpecialCells(xlCellTypeVisible).Copy

Worksheets("Sheet2").Select
Range("A1").Select
ActiveSheet.Paste

Worksheets("Sheet1").Select
Selection.AutoFilter
Application.CutCopyMode = False

End Sub

<オートフィルターで抽出した結果:シート1)
 


< シート2へコピーした結果 >



どちらかいうと、単純なデータの抽出に関しては
このほうが、分かりやすいかもしれませんね。

説明の中で「可視セルのみをコピー」という、
聞きなれない言葉がでてきましたが、これは
オートフィルターで抽出されたセルのみ対象にコピーするという命令です。

この命令がなければ抽出したデータの最終行はどこか判断して
範囲指定するコードを準備しないといけないので、これは便利な命令ですね。

 Selection.SpecialCells(xlCellTypeVisible).Copy

こんな機能があったなぁぐらいで憶えておくと役立ちますよ。

  


Posted by ミール at 09:44Comments(0)VBA

2009年07月17日

エクセルマクロ(VBA):データ抽出の基本パターン①

プログラムを作っていると、対象データを抽出するという処理が
よく出てきます。

何件かあるデータを順番よく参照していき
条件にあうデータを出力する処理を考えてみたいと思います。

方法はいくつかありますが、今日は超やさしい基本パターンを
説明していきます。

例:シート1にあるデータを参照して、条件にあうデータをシート2へ編集する。





①データ処理するに当っての取り決めをしておく。
  ①最初のデータは、2行目から始まります。
  ②氏名が空白になると、終了です。
等、条件を決めておく事が大事です。

②抽出の条件:住所が「沖縄県」の方を抽出する。

プログラムの流れ。

 最初に2行目を参照する。

 処理するデータがあるか判定する。
  氏名が空白なら、終了。
  空白でなければ、抽出判定。

 住所、つまりB列を参照し、沖縄県か判定する。

  沖縄県なら、シート2へ書き出した後、次の行を参照する。
  以外なら読み飛ばし、次の行を参照する。

そんな、単純な処理ですが、セルを参照したり
分岐したり、繰り返し(ループ)処理があったり
基本的な命令がでてきます。

次のような、マクロになります。
 
Sub 抽出処理()

Dim gyo1 As Integer '変数の定義 シート1の行番号をカウント
Dim gyo2 As Integer  '変数の定義 シート2の行番号をカウント

Application.ScreenUpdating = False '画面更新の無効
Worksheets("sheet1").Select 'シート1を選択

gyo1 = 2                '参照するデータの最初の位置:行番号の2を入れる
gyo2 = 2                '編集するデータの最初の位置:行番号の2を入れる

Do Until Range("b" & gyo1) = ""     '名前欄が空白(データ終了)になるまで繰り返す。

If Range("c" & gyo1) = "沖縄県" Then '抽出データの「沖縄県」か判定
Worksheets("sheet2").Range("a" & gyo2) = Range("a" & gyo1)  'シート2に編集する
Worksheets("sheet2").Range("b" & gyo2) = Range("b" & gyo1)
Worksheets("sheet2").Range("c" & gyo2) = Range("c" & gyo1)
Worksheets("sheet2").Range("d" & gyo2) = Range("d" & gyo1)
Worksheets("sheet2").Range("e" & gyo2) = Range("e" & gyo1)
gyo2 = gyo2 + 1          'シート2の編集する行を次の行にする      
End If
gyo1 = gyo1 + 1           '参照するデータを1行ずつ増やす。
Loop

Application.ScreenUpdating = True     '画面更新を有効にする
End Sub

マクロを実行してみると、



ここの、ポイントは変数を使って行の参照を下へ移動していくこと。
Range("c" & gyo1)・・・gyo1に2が入っていたら セルc2を参照します。
        ・・・  3が入っていたら セルc3を参照します。

この、サンプルのデータを作成して、コードをそのまま真似て作ってみると
マクロの動きが少し理解できるかもしれませんよ。  


Posted by ミール at 09:53Comments(0)VBA

2009年07月16日

エクセルマクロ(VBA):ワークシートイベントを無効にする。

エクセルマクロには、イベントという便利な機能があります。

このセルでダブルクリックすると他の表に飛んでほしいとか
このセルの内容を変えると、自動計算してほしいとか、
そんな要望に応える為、準備された機能です。

でも、そんな便利なイベントでも、処理によっては発生(起動)
させたくない時もあります。

例えば、セルの内容を変更したと同時に自動計算するマクロを作るには
Changeイベントを使います。

Private Sub Worksheet_Change(ByVal Target As Range)


End Sub

そのChangeイベントは、キーボード上からの入力だけで発生するのではなく、
マクロでセルに対して編集したときもその都度発生するので、セルに対して10回編集すれば
イベントが10回発生してしまいます。時には無限ループって事もあります。

そんな時の為に、イベントを発生させないようにする(無効)命令が準備されています。
 
例えば、下のコードを実行すると、無限ループします。
セルを編集してはイベントが起動するの繰り返しになり抜け出す事ができません。

  Private Sub Worksheet_Change(ByVal Target As Range)
  
     Range("a1").Value = "111"
     Range("b1").Value = "222"
    Range("c1").Value = "333"

  End Sub

そこで、イベントを無効にする命令、

  Application.EnableEvents = False

という命令を付け加えます。  

  Private Sub Worksheet_Change(ByVal Target As Range)
         Application.EnableEvents = False
         Range("a1").Value = "111"
         Range("b1").Value = "222"
         Range("c1").Value = "333"
         Application.EnableEvents = True
  End Sub

  これで、イベントが発生しなくなり、無限ループする事はありません。

  必ず、最後にはイベントを有効にしてあげてください。
  
  Application.EnableEvents = True・・・を忘れず。

エクセルマクロ(VBA)、奥が深いですね。
  


Posted by ミール at 09:29Comments(0)VBA

2009年07月15日

事務効率化に役立つエクセルマクロ(VBA)

エクセルマクロ(VBA)を習得すれば、事務効率が格段に向上します。

例えば、こん事例がありました。

お客さんの利用実績をエクセルで作成しているのですが、個人毎にブックを作っていました。
つまり、10人の顧客いれば、10名分のブックを作る事になります。
100人に人数が増えれば100個のブックを作る事になります。





これでは、後々管理が大変になります。

特に大変なのが、実績表のフォームに変更がでた場合、100名分のフォームを
変更していかなくてはいけません。
エクセルが使える、関数が使えるといっても膨大な作業になります。

わたしが、思いついたのが、顧客の一覧を作って、顧客のところで”ダブルクリック”
すれば、実績管理表に編集して移動するという発想。
エクセルマクロ(VBA)の得意とするところです。




      ↓  対象者でダブルクリック    




そういう、煩わしさを解決してくれのが、エクセルマクロ(VBA)です。
エクセルマクロ(VBA)だと、

 1個のブックに、利用実績のシート1枚、顧客データのシート1枚

をつくるだけで、簡単に管理できます。

又、顧客一覧が一目で見れるし、検索が簡単。実績表のフォームに変更あれば、
一つ直すだけでOKです。

エクセルが使える方なら、ほんの少し向上心を持てばマスターできます。

素人の私が、初歩的なプログラムを習得できたのですから、
そんなに難しいものではありません。

事務系の方は挑戦してみる価値はありますよ。
  


Posted by ミール at 12:33Comments(0)VBA

2009年07月14日

為になるエクセルマクロ(VBA)講座(メルマガ)の紹介

今日は、エクセルマクロ(VBA)に興味のある方へ、
是非読んでほしいメルマガを紹介したいと思います。

私の場合、このメルマガとの出会いがなければ、
たぶん、挫折していたかもしれません。

エクセルマクロ(VBA)を始めた頃は、
どんなものなのか全然わからず、
ネットや専門書を読んでみたものの、専門用語が飛び交い
とても難しいというイメージを持ってしまい、自分には
無理かなぁ~と諦めかけていました。

そんな時に、初心者向けにとても分かり易いメルマガに出会い
これなら、自分にも出来そうな気がすると実践形式の例題を
読み、試していくうちにある程度のエクセルマクロ(VBA)を
作れるようになりました。

自分にあった参考書に出会うと、マスターも早いですね。

私自信、まだまだスキルを上げる必要がありますが、このメルマガ講座の
おかげで、エクセルマクロ(VBA)が継続できたといっても過言では
ないと思っています。

ですので、もしこのブログを読んで興味をもたれた方は、是非1度、
メルマガに登録して読んでみてください。(なんてたって無料ですから!)
絶対、為になりますよ。

登録はこちらから
  ・ゴーゴーマクロ
    
http://www.wat3d.com/gogo/  
  ・エクセルマクロ成功の鉄則 (←公式テキスト購入者の方)
    
http://www.wat3d.com/vba/
  


Posted by ミール at 11:45Comments(0)VBA

2009年07月13日

ブログ再開

VBAに夢中になり過ぎて、ブログの更新もご無沙汰してます。

VBA、使い始めたら、やめられなくなりました。

プログラムを作る楽しみはもちろんですが、
周りからの要望や、感謝される喜びを味わうと
ますます、勉強しようという気持ちになり、睡眠時間
わずか、3~4時間という日が続いています。

プログラムを作る事が仕事ではない為、日常の業務を
終わらせて、家に帰ってから作るという生活になっています。

始めの頃は、単純なプログラムなので、仕事の合間に
少しずつ作っていける量でしたが、今では複雑化して
仕事と切り離してやらないと、本来の仕事自体が疎かに
なっては、リストラ回避どころか、ブラックリストですからね。

仕事の延長線だが、あくまでも片手間でやる先にリストラ回避が
あるのではと期待してます。

今は、1人ですが若い子に伝授して、仕事の効率化を追求して
行きたいと思っている今日この頃です。


  


Posted by ミール at 19:21Comments(0)日記