- ベストアンサー
Excel2000での列集計
- Excel2000での列集計についての質問です。質問文章全体は100文字程度です。
- 上の1年分のデータ表を週ごとにまとめる方法を教えてください。空白の行は削除したいです。
- マクロを使用してExcel2000での列集計を行いたいのですが、具体的な方法が分かりません。どなたか教えていただけませんか?
- みんなの回答 (5)
- 専門家の回答
質問者が選んだベストアンサー
上の行へ詰める処理を載せます。#2の補足の対処策は次回にします。 ただロジックは結構しつこく、#2の補足を拝見すると、判ってもらうのが難しいかもしれませんね。 少数例でテストしてますが、テストデータを作るのが 面倒な問題で、バグがあるかもしれませんのでその際はお許しを。 (前準備)Sheet2をそっくりsheet3にコピーしてください。 (後処理)まだ空白行を省く処理が残っていますが、手作業で行削除をされてはどうですか。 (コード) Sub test02() Dim sh3 As Worksheet Set sh3 = Worksheets("sheet3") d = sh3.Range("d3").CurrentRegion.Rows.Count r = sh3.Range("d3").CurrentRegion.Columns.Count ' MsgBox d ' MsgBox r d = d + 1 sh3.Cells(d, 1) = "end" '終わりをわざと作る s = 3 mkey = sh3.Cells(3, 1) & sh3.Cells(3, 2) & sh3.Cells(3, 3) For i = 3 To d key = sh3.Cells(i, 1) & sh3.Cells(i, 2) & sh3.Cells(i, 3) If mkey <> key Then '---同じキーブロック内で上へ詰める処理 l = i - 1 ' MsgBox s & "=" & l For j = 4 To r '全列左より右へ For k = s + 1 To l '同じキーブロック内で For m = k To s + 1 Step -1 If sh3.Cells(m - 1, j) = "" Then sh3.Cells(m - 1, j) = sh3.Cells(m, j) sh3.Cells(m, j) = "" End If Next m Next k Next j '-------- s = i '同じキーブロックの先頭行を置換え Else 'キーが変らない行の処理 End If mkey = key Next i '-----最後処理 sh3.Cells(d, 1) = "" End Sub
その他の回答 (4)
- imogasi
- ベストアンサー率27% (4737/17069)
>D2のセルから月~日の繰り返しで、20030630は月で終わっています-->ではD1・E1・F1・・・の第1行は何が入っていますか。 D3・E3・F3・・・は何が入っていますか。曜日ですか。 D1=,D2=、D3=、E1=、E2=,E3=、F1=、F2=,F3=に何が入っているか実例で書いてみてください。 >どうも、半年分のデータを全てE列に集まる形になっているようですが-->NO。月曜日にその1週間分をまとめているつもり。基本は間違っていないとおもう。ただ大切な「日付」の入力セルや文字列かエクセル本来の日付け 方式でないなどの説明が不十分で、食い違いが出ているかも。日付けの捉え方が狂うと結果はすべてだめ。 >1行目 20030106~ 20030112 20030113~ 20030119 と 2行目は、D2のセルから月~日の繰り返しで、20030630は月 -->矛盾していませんか。1行と2行目とどちらなんですか。 >その表のD列~J列(1/6~1/12の週)のデータをD列(月曜日の列)に集め、 -->私は2003/1/1から始まると思っていましたが、1月6日から始まるのですか。 D1は1月6日? >その次の週のデータはF列にという具合に最後の列のGD列(6/30)まで続けます。 -->月末日を関係なく、半年を 月-日曜のスパンで、月曜日に横に縮めるイメージですね。この点ではこのつもりで作りました。また私は曜日は 日付から割り出しているので、セルに月・火・水があっても使いません。 ●本件のような、業務・仕事の丸投げ的課題は、(1)テストデータが当方で作りにくく(2)細かい会社のルール やニーヅや業界慣習が伝わらず(3)スキルについても あれこれいえず(4)質問の意味を捉えるのが苦労あり(5)メールでの応答だけのやり取りなどの制約があって難しいと思います。 ある程度回答者が組んだプログラムが読めて、その意を汲んで、質問者側で、不適当部分は正し、チューニングできないと難しいと思います。仕事問題をOKWEBでやるのは難しいと判るのも経験ですが。 あと多少は付き合いますが、よろしく。
- imogasi
- ベストアンサー率27% (4737/17069)
#2の補足に付いて ●半年分--->それならわかります(質問には書いてない) ●DateSerial(y1, m1, d1)のところで引っかかってしまいました。---> (1)1行目には、D1のセルから右に20030106~20030630までこのような形で入力されていると考えてください。 --->文字列で入っているのですね。(これも質問に書いてない。) 私の元(#2)のy1,m1,d1を s = sh1.Cells(1, j) '第1行第j番目列 y1 = Val(Mid(s, 1, 4)) m1 = Val(Mid(s, 5, 2)) d1 = Val(Mid(s, 7, 2)) ds = DateSerial(y1, m1, d1) ys = Weekday(ds) に置き換えて下さい。但しds=、ys=の部分は変更なし。 ●A,B、C・・などの実質のデータが入るのは(3,4)から、右且つ下で良いですね。 ●2行目は、D2のセルから月~日の繰り返しで、20030630は月で終わっています。 ---->私には理解できません。 なぜ繰り返しなのか。
補足
imogasiさん、どうも私の説明が悪いようで通じていないようです。 まず最初にExcelで256列以上入力不可能と知らなかったので、 1年分を一騎に処理しようと思っていましたが、半年分の処理に変更しました。 そして、全て文字列になっています。 ●A,B、C・・などの実質のデータが入るのは(3,4)から、右且つ下で良いですね。 その通りです。 ●2行目は、D2のセルから月~日の繰り返しで、20030630は月で終わっています。 ---->私には理解できません。なぜ繰り返しなのか。 ここが通じていなかったようです。 どうも、半年分のデータを全てE列に集まる形になっているようですが、 元の表は、1行目(年月日)はD1のセルより、2行目(曜日)はD2のセルより右に 1行目 20030106~ 20030112 20030113~ 20030119 2行目 月 火 水 木 金 土 日 月 火 水 木 金 土 日 のように20030630の月曜日まで続きます。 最後の週のみ6月30日の月曜日で切れています。(7月のデータはいりません) その表のD列~J列(1/6~1/12の週)のデータをD列(月曜日の列)に集め、 続いてK列~Q列(次の1/13~1/19の週)のデータをE列(この列が1/13~1/19の週の列になる)に集めて、 その次の週のデータはF列にという具合に最後の列のGD列(6/30)まで続けます。 D列からAD列までの27列が残るはずで、1行目にはD~AD列まで全て月曜日の日にちのみが右に並び、 2行目には"月"のみが右に並んでいるようにしたいのです。 そして第2段階の行の削除なのですが、これは同人のデータのみでの処理です。 長くなりました、すみません。 宜しくお願いします。
- imogasi
- ベストアンサー率27% (4737/17069)
マクロが判らないというより、フローチャート(ロジック)作成の問題と認識すべきです。 補足に対する回答有難うございました。判りました。 2ステップに分けるほうが判り易いと思いますので分けます。 まず列を縮約する処理を下記に載せます。少数例でテスト済み。 (仮定1)第1行は毎日(列)に、月数字が入っていると仮定。今年2003年と仮定。 (仮定2)月を越えて次の月曜がある週で、月末で切っていない。(月末までと月初から月曜までに分けていない) (仮定3)1表は256列が限度ですが(365日入れられませんが、)どうするか、疑問のまま256列以内と仮定。 (1)源データ(Sheet1)の保存、繰り返しテストのやりやすさのために、別シートSheet2に目的の結果データを作る。 (2)下記プログラムロジックとなる。 (A)初期値セット。 Sheet1のセル(3,3)よりスタート。 i=3、j=4 Sheet2もセル(3,4)よりスタート。 k=3,m=4 (B)Sheet1の最下行か---->処理終わり。 最下行を調べfor・nextでやればこのステップなし。 Sheet1の最右行か---->この行の処理終わり。次行の処理へ。i=i+1 最下行を調べfor・nextでやればこのステップなし。 (C)Sheet1の最右列か----><であるとき> Sheet1の 次ぎの行へ進む i=i+1。 そして(B) へ。 (D)月曜日か(1行j列&2行j列で曜日判定)--> <であるとき> 月日セット。 Sheet2でm=m+1。 <でないとき> (E)へ。 (E)セル(i,j)は空白か。-->(G)へ。 (F)Sheet1のセル(i,j)をSheet2のセル(k、m)へセット。(前日等と同じでも上書きする。ロジックを単調にするため) (G)Sheet1の次ぎの列へ進む。j=j+1 (H)(C)へ行く。 ----------------- Sub test01() Dim sh1, sh2 As Worksheet Set sh1 = Worksheets("sheet1") Set sh2 = Worksheets("sheet2") d = Range("d3").CurrentRegion.Rows.Count r = Range("d3").CurrentRegion.Columns.Count '---- For i = 3 To d k = i m = 4 sh2.Cells(1, m) = sh1.Cells(1, 4) sh2.Cells(2, m) = sh1.Cells(2, 4) m = m + 1 For j = 4 To r '------ y1 = 2003 m1 = sh1.Cells(1, j) d1 = sh1.Cells(2, j) ds = DateSerial(y1, m1, d1) yb = Weekday(ds) '---月曜日か If yb = 2 Then sh2.Cells(1, m) = sh1.Cells(1, j) sh2.Cells(2, m) = sh1.Cells(2, j) m = m + 1 End If '----セル空白でないか-- If sh1.Cells(i, j) <> "" Then sh2.Cells(k, m) = sh1.Cells(i, j) End If Next j Next i End Sub
補足
imogasiさん、早々のご回答ありがとうございます。 ですが、私の知識では少し難しいようで理解できません。すみません。 Sub test01() からEnd Subまでがマクロですよね。 これをVBAのModule1に貼り付けさせていただき実行したところds = DateSerial(y1, m1, d1)のところで引っかかってしまいました。 多分1行目の仮定が違うせいだと思うのですが、私には直す事ができません。 ちなみに1行目には、D1のセルから右に20030106~20030630までこのような形で入力されていると考えてください。(半年分) 2行目は、D2のセルから月~日の繰り返しで、20030630は月で終わっています。 どこを変えればいいのか、教えていただけると助かります。 何度も申し訳ありませんが、宜しくお願いいたします。
- imogasi
- ベストアンサー率27% (4737/17069)
●「同人の行の中ではひとつの行には同じデータしかない」らしいが、確かに元データ例ではそうなっている。 ●しかしまとめた表では 「a1 111 あ C B」 や「a2 222 い B A」 では異種が混じっている。(CとB、BとAなど)。 ●これはどういうことですか。上下行のまとめ(縮約)はするのですか。
補足
imogasiさん、分かりにくくてすみません。 まず同人の1週間(1/1~1/7)のデータを全て1/1(月)の列にまとめ Code1 Code2 Name 1 8 ~ 月 月 a1 111 あ A A a1 111 あ B a1 111 あ C C a2 222 い A a2 222 い B a2 222 い C C a2 222 い D a3 333 う A a3 333 う B このような形にしてから、データの欄の空白セルを削除して上に詰めて、データの無くなった行を削除して Code1 Code2 Name 1 8 ~ 月 月 a1 111 あ A A a1 111 あ C B a1 111 あ C a2 222 い B A a2 222 い C C a2 222 い D a3 333 う A B という形にしたいのです。 本当に分かりにくくてすみませんでした。 宜しくお願い致します。
お礼
imogasiさん、お礼が遅くなって申し訳ありませんでした。 今回の質問では、私の知識不足により、せっかくご回答をいただいたのに活用できず、ご迷惑をおかけ致しました。 あれから2ヶ月程、日々インターネットで私でも理解できるフリーのサンプルマクロを見つけ、私なりに切り貼り変更し、どうにか使えるマクロができあがりました。 imogasiさんよりNo.3でご回答頂いたマクロも使わせていただきました。 本当にありがとうございました。 よって、この質問は締め切らせて頂きます。 失礼いたします。
補足
元の表は(多少忠実な表にした為、最初に質問した時の表とは少し変わります。) 1行目が年月日の行です。 A1=ブランク,B1=ブランク,C1=ブランク,D1=20030106,E1=20030107,F1=20030108,G1=20030109,・・・・・FW1=20030630 2行目が曜日の行です。 A2=ブランク,B2=ブランク,C2=ブランク,D2=月,E2=火,F2=水,G2=木,H2=金,I2=土,J2=日,K2=月,L2=火,M2=水,・・・・・FW2=月 3行目からデータが入っています。(A列はCode1,B列はCode2,C列はName,D列からデータ) A3=a1,B3=00111,C3=あ,D3=A,E3=A,F3=ブランク,G3=ブランク,H3=ブランク,I3=ブランク,J3=ブランク,K3=ブランク,L3=A,M3=ブランク,・・・・・ A4=a1,B4=00111,C4=あ,D4=ブランク,E4=ブランク,F4=ブランク,G4=ブランク,H4=ブランク,I4=ブランク,J4=ブランク,K4=B,L4=B,M4=ブランク,・・・・・ A5=a1,B5=00111,C5=あ,D5=ブランク,E5=C,F5=C,G5=C,H5=ブランク,I5=ブランク,J5=ブランク,K5=C,L5=ブランク,M5=ブランク,・・・・・ A6=a2,B6=00222,C6=い,D6=ブランク,E6=ブランク,F6=ブランク,G6=ブランク,H6=ブランク,I6=ブランク,J6=ブランク,K6=ブランク,L6=A,M6=A,・・・・・ A7=a2,B7=00222,C7=い,D7=B,E7=B,F7=ブランク,G7=ブランク,H7=ブランク,I7=ブランク,J7=ブランク,K7=ブランク,L7=ブランク,M7=ブランク,・・・・・ A8=a2,B8=00222,C8=い,D8=ブランク,E8=C,F8=C,G8=ブランク,H8=ブランク,I8=ブランク,J8=ブランク,K8=ブランク,L8=C,M8=C,・・・・・ A9=a2,B9=00222,C9=い,D9=ブランク,E9=ブランク,F9=ブランク,G9=ブランク,H9=ブランク,I9=ブランク,J9=ブランク,K9=ブランク,L9=D,M9=ブランク,・・・・・ A10=a3,B10=00333,C10=う,D10=A,E10=A,F10=ブランク,G10=ブランク,H10=ブランク,I10=ブランク,J10=ブランク,K10=ブランク,L10=ブランク,M10=ブランク,・・・・・ A11=a3,B11=00333,C11=う,D11=ブランク,E11=ブランク,F11=ブランク,G11=ブランク,H11=ブランク,I11=ブランク,J11=ブランク,K11=B,L11=ブランク,M11=ブランク,・・・・・ このように行数は結構な量があり、人数が何人なのか同人の行が何行あるのかも数えられる量ではありません。縦に1699行、横はFWの列が最終列になっている表です。 >私は2003/1/1から始まると思っていましたが、1月6日から始まるのですか。D1は1月6日?< はい、すみません。これも今年のカレンダー通りに変更させていただきました。 今年の最初の月曜日からという事です。 文字列かどうかの件ですが、これはセルの書式設定の表示形式においてB3からB1699(データの入っている最後の行が1699行なので)までのセルが文字列になっていて、その他のセルは標準になっています。 B列のCode2のみ数字の頭に0が付くので、文字列にする必要があります。 最初は、Sheet1全てのセルを文字列にしていたのですが、どちらにしたらいいのでしょうか?この設定もなんらかの影響を受けていると思うので教えて頂けるとうれしいです。 私の知識不足で大変ご迷惑をおかけしています。 >ある程度回答者が組んだプログラムが読めて、その意を汲んで、質問者側で、不適当部分は正し、チューニングできないと難しいと< 本当にその通りです。"丸投げ的課題"になってしまい恥ずかしいかぎりです。 ですが、どうかもう少しだけお付き合い願えないでしょうか? お願いします。