こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

解決済みの質問

VBAでのデータ並び替え、条件判断について

Excel2003、VBA6.5でマクロに挑戦しているVBA初心者です。
学生時代にプログラムはかじった事があるのですが、マクロは勝手が分からず、
以下のようなマクロを組みたいのですが、そもそもプログラムはどこの
ウィンドウに書くのか?という辺りから調べ出す始末のため、皆様の
お知恵をお借りしたく、投稿しました。

【目的】
Sheet1に貼り付けられたデータを、精査(並び替え、条件判断)し、結果をSheet2に出力させたい。

Sheet1(入力データ)
1行目は項目名
データA1,データB1,データC1,データD1,データE1
データA2,データB2,データC2,データD2,データE2


データA11,データB11,データC12,データD11,データE11
データA12,データB12,データC12,データD12,データE12

※データEのみ、整数型で後は文字データになります。
 また行数というか、データ量は20~30行程度を想定してます。


Sheet2(出力データ)
1行目は項目名
日付,データB1+データC1の文字列を結合,固定値2,条件判断結果1(データD1より条件判断)
日付,データB2+データC2の文字列を結合,固定値2,条件判断結果2(データD2より条件判断)

※Sheet1のデータ1行は、すべてが必要でありません。一部のみがあればOKです。
 上記の例だと、Sheet1のデータAとEはSheet2では不要です。
※日付…マクロを走らせた日付をMM/DD形式で出力させたい
※条件判断結果…(データD1がAMだったら09:00、PMだったら13:00、PM2だったら15:00という値を返すようにしたい)

流れを考えてみましたが、

1)データ型を宣言して、
2)1行を配列に読み込む
3)
a)データB列、C列の文字列を結合
 b)データD列の条件分岐
4)配列からデータを書き出す
5)Sheet1の行が空白だったら処理完了

という感じかと思っているのですが、具体的にマクロにできず(関数をうまく使えず)、困っています。
Findメソッドか、Vlookupあたりで必要になるデータだけ、Sheet1で検索した結果をSheet2に埋めて
行く形でもできるのかな、とも思いましたが、こちらも具体的にマクロにできません。

特に処理スピードにこだわるわけではないですが、あとあと見返して勉強およびメンテできるような、
シンプルなカタチ(1行にコマンドを詰め込んだ複雑な形ではなく)にしていただけると助かります。
どうぞご教授いただけませんでしょうか。
よろしくお願いいたします。

投稿日時 - 2011-07-20 01:21:28

QNo.6886887

すぐに回答ほしいです

質問者が選んだベストアンサー

マクロは標準モジュールに書きます。

方法1:エクセルはエクセルらしく使います
sub macro1()
 dim r as long
 r = worksheets("Sheet1").range("A65536").end(xlup).row

 with worksheets("Sheet2")
  .range("A:A").numberformatlocal = "MM/DD"
  .range("D:D").numberformatlocal = "h:mm"

  .range("A2:A" & r) = date
  .range("B2:B" & r).formula = "=Sheet1!B2&Sheet1!C2"
  .range("C2:C" & r) = "固定値2"
  .range("D2:D" & r).formula = "=IF(Sheet1!D2=""AM"",TIME(9,0,0),IF(Sheet1!D2=""PM"",TIME(13,0,0),IF(Sheet1!D2=""PM2"",TIME(15,0,0),"""")))"
 end with

'以下は必要に応じて
 with worksheets("Sheet2")
  .range("B2:B" & r).value = .range("B2:B" & r).value
  .range("D2:D" & r).value = .range("D2:D" & r).value
 end with
end sub


#補足
>必要になるデータだけ、Sheet1で検索した結果をSheet2に埋めて

詳細がないため盛り込んでいません。



方法2:エクセルを使いたくない人向けの書き方です
sub macro2()
 dim r as long, i as long, res as variant
 r = worksheets("Sheet1").range("A65536").end(xlup).row
 worksheets("Sheet2").range("A:A").numberformatlocal = "MM/DD"
 worksheets("Sheet2").range("D:D").numberformatlocal = "h:mm"


 for i = 2 to r
  worksheets("Sheet2").cells(i, "A") = date
  worksheets("Sheet2").cells(i, "B") = worksheets("Sheet1").cells(i, "B") & worksheets("Sheet1").cells(i, "C")
  worksheets("Sheet2").cells(i, "C") = "固定値2"
  select case worksheets("Sheet1").cells(i, "D")
  case "AM"
   res = timeserial(9, 0, 0)
  case "PM"
   res = timeserial(13,0,0)
  case "PM2"
   res = timeserial(15,0,0)
  case else
   res = ""
  end select
  worksheets("Sheet2").cells(i, "D") = res
 next i
end sub


#補足
エクセルのワークシート上には既に「配列」っぽくデータが配置済みです。
もちろん具体的な状況に依りますが,わざわざメモリに値を転送してから計算するより,直接セルから値を取り出して演算したり,直接転記した方が少し高速な場合もあります

投稿日時 - 2011-07-20 13:50:10

お礼

keithin様

ご回答いただき、ありがとう御座います。

方法1を使い、データ項目を増やしたりして(本来は項目が20程あるのです)テストしていますが順調に動いており、厚く御礼申し上げます。

もし可能でしたら、追加で1つだけお教えください。
方法1の、
.range("B2:B" & r).formula = "=Sheet1!B2&Sheet1!C2"
のデータB+データCの結合の部分で、データBとCの間にスペースを入れるように変更を行ってみるべく、
"=Sheet1!B2&" "&Sheet1!C2"
等、幾つか自分なりに調べてみた結果を試したのですが、
コンパイルは問題なく通るものの、シートにはNULLやVALUE
表示になってしまいます。
表示されるような方法はあるのでしょうか。

(方法2なら、cells(i, " ")とかをBとCのデータを表示される間に入れてやることで解決できそうな気はするのですが…

投稿日時 - 2011-07-22 00:04:27

ANo.1

このQ&Aは役に立ちましたか?

0人が「このQ&Aが役に立った」と投票しています

回答(2)

ANo.2

.range("B2:B" & r).formula = "=Sheet1!B2&"" ""&Sheet1!C2"

といった具合で,必要な書きぶりは前回回答でD列に式を入れさせているマクロのほぼそのままです。
追加ご質問から1日置いてもそのまま解決されていないところを見ると,見直し等されていない様子で大変残念です。


また,新しいマクロの記録で実際に「セルに必要な式を記入する」という操作をマクロに録ってみるのも,正しい書きぶりを知るよい手がかりなので,参考になさってみてください。

投稿日時 - 2011-07-22 19:40:06

お礼

すみません、別件の仕事で確認が滞っていました。
スペースについてはお陰様で無事に解決しております。
もっとコードをいじってみて、お教えいただいた事を吸収できるよう、精進していきたいと思います。
本当にありがとう御座いました。

投稿日時 - 2011-07-25 21:51:00

あなたにオススメの質問