• 締切済み

エクセル・VBAで決められたルールで転置をするには?

現在エクセル上で以下の様なデータ処理を行っています。 c05 p2 v1 v5 空白セル b07 b11 空白セル b07 空白セル a06 a07 a09 i1 i6 j8 p9 s1 というデータを c05 p2 v1 v5 p2 v1 v5 v1 v5 v5 空白セル b07 b11 b11 空白セル b07 空白セル a06 a07 a09 i1 i6 j8 p9  s1 a07 a09 i1 i6 j8 p9 s1 a09 i1 i6 j8 p9 s1 i1 i6 j8 p9 s1 i6 j8 p9 s1 j8 p9 s1 p9 s1 s1 とこのように転置を行いたいと考えています。 数千行ならばマクロの記録などを利用しやる事も出来るのですが、データ量が50万行と非常に多いのでこれらの作業を一括で行いたいと思い質問させて頂きました。 このような作業をするにはVBAでやるのが早いと思うのですが、どのような処理をさせたらいいのでしょうか? またなにか参考になるサイト・参考書等がありましたら教えてください。

みんなの回答

  • imogasi
  • ベストアンサー率27% (4737/17068)
回答No.6

>転置 Transposeといウと思うが、エクセルでは特別な意味がある。適当でない。「並べ替え組み合わせ」程度の表現が良いかと。 >長々と質問に例を挙げていて、それなりに理解の助けになるが、どういう仕組みかを考え、質問に文章でも表現するクセをつけないと。 ーー 空白まで行数をnとして、最上行から数えて、n、n-1,n-2、・・・2,1個取るが、x個を取る行数を1つずつ下げている。 こういうことでよいのかな。 ーー 例データ A列A1:A18 c05 p2 v1 v5 b07 b11 b07 a06 a07 a09 i1 i6 j8 p9 s1 ーー 標準モジュールに Sub test01() d = Range("a65536").End(xlUp).Row MsgBox d s = 1 'スタートセル k = 1 '結果のスタート行 m = 8 '結果のスタート列 Range("A1").Select Range("a1:A100").Select '範囲を100行と仮定 '---以下繰り返し Do While s < d n = Selection.Find(What:="").Row 'A列で空白行を見つける l = n - s '空白から空白までのセル数 MsgBox n For i = 0 To l - 1 For j = s + i To n Cells(k, m) = Cells(j, "A") m = m + 1 '1列右へ Next j m = 8 '結果のスタート列 k = k + 1 '一行下へ Next i '--検索範囲の取り直し Range(Cells(n + 1, "A"), Cells(100, "A")).Select s = n + 1 'スタートセルを設定し直し Loop End Sub ーー 結果(この場合H列から右に) c05 p2 v1 v5 p2 v1 v5 v1 v5 v5 b07 b11 b11 b07 a06 a07 a09 i1 i6 j8 p9 s1 a07 a09 i1 i6 j8 p9 s1 a09 i1 i6 j8 p9 s1 i1 i6 j8 p9 s1 i6 j8 p9 s1 j8 p9 s1 p9 s1 s1 少しの修正で済むはずだが、これを本番用に作り直せるかな。 なるべく範囲のスタートとエンドを小刻みに分割して、実行することをお勧めする。 こういう2重ループのロジックのプログラムは相当慣れないと混乱すると思うが、行数が少なくはなる。 なおMsgboxは確認用なので、本番ではその行を削除のこと。

  • zap35
  • ベストアンサー率44% (1383/3079)
回答No.5

#04です。 #04のマクロよりも#02さんの回答の方がアルゴリズムは圧倒的に優れています。脱帽です。 そこで#04を書き換えました。別シートに書き込むところは先の回答と一緒ですので3、4行目を修正してください Sub Macro2() Dim idx, cnt As Long Const sht As String = "Sheet2" Const clm As String = "A" Application.ScreenUpdating = False With ActiveSheet   For idx = .Cells(.Rows.Count, clm).End(xlUp).Row To 1 Step -1   If .Cells(idx, clm).Value = "" Then     cnt = 0   Else     Sheets(sht).Cells(idx, 1).Value = .Cells(idx, clm)     If cnt > 0 Then       Sheets(sht).Cells(idx + 1, clm).Resize(1, cnt).Copy Sheets(sht).Cells(idx, 2)     End If     cnt = cnt + 1   End If   Next idx End With Application.ScreenUpdating = True End Sub

  • zap35
  • ベストアンサー率44% (1383/3079)
回答No.4

>どのような処理をさせたらいいのでしょうか? プログラムの経験はおありですか? もしあまり経験がないなら、アルゴリズムを考えるのがかなりつらいと思いましたので、とりあえずサンプルを書きました。 以下のマクロをALT+F11でVBE画面を開き、左上のVBA Projectでシート名を右クリックし「挿入」→「標準モジュール」で表示される画面に貼り付けて下さい。マクロの実行は元データが入力されているシート画面に戻ってALT+F8でマクロ一覧を開き、マクロ名を選択して「実行」ボタンです。 (2007なら開発リボンは表示しておいてくださいね) 並べ替え結果は別シートに書き込むようにしました。マクロの5、6行目は実際の列名とシート名に変更してください Sub Macro1() Dim idx, frm, cnt As Long Dim ptr2, idx2 As Long Const clm As String = "A" '元データが書かれている列名 Const sht As String = "Sheet2" '並び替え結果を書き込むシート名  Application.ScreenUpdating = False  frm = 0  cnt = 0  ptr2 = Sheets(sht).Cells(Sheets(sht).Rows.Count, "A").End(xlUp).Row + 1  With ActiveSheet   For idx = 1 To .Cells(.Rows.Count, clm).End(xlUp).Row + 1    If .Cells(idx, clm) <> "" Then     cnt = cnt + 1     If frm = 0 Then      frm = idx     End If    Else     If cnt > 0 Then      .Cells(frm, clm).Resize(cnt).Copy Sheets(sht).Cells(ptr2, "A")      For idx2 = 1 To cnt - 1       Sheets(sht).Cells(ptr2, "A").Offset(idx2, 0).Resize(cnt - idx2).Copy _        Destination:=Sheets(sht).Cells(ptr2, "A").Offset(0, idx2)      Next idx2      ptr2 = ptr2 + cnt + 1      frm = 0      cnt = 0     End If    End If   Next idx  End With  Application.ScreenUpdating = True End Sub なお「マクロが分からないから解説、修正してください」はナシです。 それはご自身がマクロを勉強して行ってください。エラーが発生した場合はその限りではありません。

回答No.3

ANo.2です。 wがintegerを超える可能性があるので、 Dim w As Integer を Dim w As Long に変更してください。

回答No.2

c05 p2 v1 v5 というのが、 A1=c05,B1=p2,C1=v1,D1=v5 なのか、 A1=c05 p2 v1 v5 なのかわからないので、両方考えました。 考え方としては、最後の行から処理した方が楽だという事です。 ----------------------- 'cell毎にデータを配置する場合 Sub test1() Dim ws As Worksheet Dim row As Long Dim w As Integer Set ws = Worksheets("sheet1") '目的のシート For row = ws.Cells(ws.Rows.Count, 1).End(xlUp).row To 1 Step -1 If ws.Cells(row, 1) = "" Then w = 0 Else w = w + 1 If w > 1 Then ws.Range(ws.Cells(row + 1, 1), ws.Cells(row + 1, w - 1)).Copy Destination:=ws.Cells(row, 2) End If End If Next End Sub ----------------------- 'A列にデータを配置する場合 Sub test2() Dim ws As Worksheet Dim row As Long Dim w As Integer Set ws = Worksheets("sheet1") '目的のシート For row = ws.Cells(ws.Rows.Count, 1).End(xlUp).row To 1 Step -1 If ws.Cells(row, 1) = "" Then w = 0 Else w = w + 1 If w > 1 Then ws.Cells(row, 1) = ws.Cells(row, 1) & " " & ws.Cells(row + 1, 1) End If End If Next End Sub p.s. excel2000で試しました・・・

  • pbforce
  • ベストアンサー率22% (379/1719)
回答No.1

ヒント セルのコピー1 Cells(1,2)=Cells(2,1)でA2セルの内容をB1にコピー。 セルのコピー2 Cells(1,2)=Cells(2,1) & " " & Cells(3,1)でA2セル、スペース、A3セルとしてB1にコピー。 空白セルの判断 If Cells(2,1)="" Then ~~ End If A2セルが空白なら~~を実行します。 繰り返し For i=1 To 50000 ~~~ Next i iを1,2,3,4・・・と変化させながら~~~を実行する。 途中で終わらせたいときは、Exit Forとする。 以上を組み合わせれば、作れます。 でも、よく見たら50万行のデータはエクセルの1シートでは処理できません。 複数シートに分かれていて全部で50万行ですか?

chun1222
質問者

補足

回答ありがとう御座いました。 50万行のデータですが、エクセル2007を利用しておりますので、1シートで作業しています。

関連するQ&A

  • 転置行列の成分について

    線形代数学の転置行列について質問です A=(aij),B=(bij)を(m,n)型行列とするとき、Bの転置行列tBの第i行の成分を書き下せ。 という問題なのですが、 僕は「tBの第i行成分はBの第i列成分と等しいので b1i ,b2i ,…,bmiとなる」のだと思っていたのですが、友達に聞くと 「b1j,b2j,…,bmj」だと言われました。 そもそも「tB1の~」という部分が僕の考え間違いなのでしょうか。 どなたかわかりやすく教えてください、よろしくお願いします。

  • エクセルのvbaの質問

    a b c d e f g h i j k l m n 1 p1 p2 p3 2 s1 s2 s3 s4 s1 s2 s3 s4 s1 s2 s3 s4 3 あ い う お え い あ う お え い 4 10 25 20 40 25 50 10 30 20 15 17 5 6 7 p1 p2 p3 8 =a3 =b3 =c3 =d3 9 =a4 =b4 =c4 =d4 こんな感じでデータが入ってます。 p1の内訳がs1からs4という感じです。 で、a7からc3にp1,p2,p3とありますが、これをクリックしたら、 またはa7にp1とかp2と入力したら、a8からd9にそれぞれの内訳が参照されるようなマクロを組みたいのです。 どうか教えてください。 見づらいですね。 データはa1,f1,k1にそれぞれp1,p2,p3 a2からd2,f2からi2,k2からn2にそれぞれs1,s2,s3,s4 a3あ,b3い,c3う,d3"",e3"",f3お,g3え,h3い,i3あ,j3"",k3う,lお, m3え,n3い a3 10,b3 25,c3 20,d3 "",e3 "",f3 40,g3 25,h3 50,i3 10,j3 "",k3 30,l3 20,m3 15,n3 17 a7 p1,b7 p2,c7 p3 a8からd9の"=a3"から"=d4" です。 3行目、4行目は必ずしも全部埋まってなくて、スペースが入る場合があります。 よろしくお願いします。

  • エクセル マクロ VBA

    エクセルのマクロについて質問です。 『集計』というブックの『集計開始』というシートに     A列    B列     C列 1行目 見出し  見出し   見出し      (商品名)  (支店)  (個数)         2行目 コメント  空白     空白   3行目 空白   空白     空白 4行目 商品名  支店     個数  5行目 空白   空白     空白 6行目 空白   空白   コメント1 7行目 空白   空白     空白 8行目 空白   空白   コメント2 9行目以降    上記のデータ(見出しを除く)の繰り返し というデータが入っています。 B列の中に『AAA』という文字が含まれていたら、そのセルを空白に置換し、 含まれていなかったら、そこで処理がとまったりエラーが出たりしないで次のステッップへ進み、 C列の中に『B』という文字が含まれていたら、そのセルを空白に置換し、 含まれていなかったら、そこで処理がとまったりエラーが出たりしないで次のステッップへ進み、 (今は、手作業で編集→置換→検索する文字列の中に『B*』と入力し、 置換後の文字列を空白にしてすべて置換ということをやっています。)                            ABC列(データーの入っている行まで)の空白を含む行を一括削除し、 以下のような形にしたいのです。     A列    B列     C列 1行目 見出し  見出し   見出し      (商品名)  (支店)  (個数)         2行目 商品名  支店     個数  3行目 商品名  支店     個数          ・         ・ このようにするマクロ文はどのようになりますでしょうか?

  • Excel マクロ・VBAの印刷方法について

    急ぎの回答です!! 関数式の入っているセル(空白表示)を印刷範囲に入れずに印刷する方法を教えてください。 別シートのデータを関数で引っ張てきてひな形のセルに表示しています。 行→$1:$6 列→$A:$Agは印 刷タイトルに設定。 A列7行目から1.2.3... とNo.が入っており、 B.~J. 列7行目からはデータが最終の50まで入力してます。( 関数式=IF(COUNTIF(コード,$S$1)<ROW(A1),"",OFFSET([元リスト.xlsx]商品一覧!A1,MATCH($S$1,コード,0),1)) ) K.~AG.列7行目からは書式データ(同じ文面の繰り返です。最終の50まで入っています)B~J列の7行目から関数(データ)=IF(COUNTIF(コード,$S$1)<ROW(A1),"",OFFSET([元リスト.xlsx]商品一覧!A1,MATCH($S$1,コード,0),1))をコピぺと一部を変更しセルへ入力して別シートからデータを引っ張てきてます。この関数だと該当する値がない場合はセルは表面上は空白セルに見えますが、セルには数式が入っている状態です。セルデータの最終行を習得し印刷に設定すると関数入力されているところで最終行と認識し、関数式を入れている50行まで印刷してしまいます。 したいことは、データが表示されている30行までなら30行まで印刷という感じにはできないでしょうか? シートを様式一枚ずつ作成しており、1ブックには20シートずつ保存しています。そしてこのブックはおよそ30ブックあります。 1ブック内の全てのシート(20シート)に反映できるようしたいです。 ※30行までデータが表示されている場合、C~Jには途中とちゅうで空白欄がありますが、B列は30行全てデータの表示(該当する場合)されます。 Excel マクロ VBA に詳しい方回答お願いします! B7からはB56まですべて関数式を入力しています(最大50までデータが表示されるように) シート枚数と、元のデータ数が行で7000程とかなり多く、このような関数式になりました。できればマクロ、VBA等での処理が望ましいです(時間がないので><)よろしくお願いいたします!!!

  • Excel VBAによる検索処理?

    Excelで以下の例のように、A列・B列に入力されているとします。A列を検索して、C列にB列の値を返す式を考えてますが、さっぱりわかりません。VBAとかも正直素人ですが、サンプルもしくは考え方を教えていただければと思います。以下の処理内容です。 ・AXセルが「B」であった場合、次のセル(A(X+1))を検索し、次が空白になるまで検索し、空白になる前の最後の行のB列の値をCXセルに返す。該当しない場合は空白のまま 下記の例ですと3行目、8行目のB列の値を2・3、6-8行目のC列のセルに返すことになります。よろしくお願いいたします。 (処理前) ___A__B__C ------------- 1 2__B__2 3__B__3 4______4 5______5 6__B__6 7__B__7 8__B__8 9______9 (処理後) ___A__B__C ------------- 1 2__B__2__3 3__B__3__3 4______4 5______5 6__B__6__8 7__B__7__8 8__B__8__8 9______9

  • エクセル 文字列を分割するマクロについて

    1行目から200行目くらいまで、A列に次のようなデータが入っています。 (A1セル) A 1 A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S このデータを下記のようにカンマごとに別のセルに分割するマクロを 教えていただけないでしょうか。 A1に「A」を、S1に「S」を入れたいと思っています。  A B C ・・・ R S 1 A B C ・・・ R S

  • 転置行列 証明

    転置行列 証明 t(AB)=t(B)t(A) の証明について。 (l,m)行列をAとしてAの(i,j)成分をa(i,j) (m,n)行列をBとしてBの(i,j)成分をb(i,j) 2つの行列の積の(i,j)成分は Σ[k=1~m]a(ik)b(kj)と定義されます。 ABの転置行列t(AB)の(i,j)成分t(AB)(i,j)=(AB)(j,i) よって、 Σ[k=1~m]a(jk)b(ki)・・・(1) =Σ[k=1~m]t(a(jk))t(b(ki))・・・(2) =Σ[k=1~m]a(kj)b(ik)・・・(3) =Σ[k=1~m]b(ik)b(kj)・・・(4) =t(B)t(A) 上は参考書などでよく見る証明なのですが、(3)ってそもそも計算できるのですか? (1)~(4)までの流れは理解できるのですが、(3)を等式でつないでいいのかと気になりました。 (l,m)行列と(m,n)行列の積は(l,n)行列と定義されますが、(3)とは関係ないのでしょうか? ご回答よろしくお願い致します。

  • 転置行列と行列の和

    初めまして。 大学の授業でプログラミングのC言語を勉強しています。 4月からプログラミングを始めたばかりで、まったくの初心者です。 転置行列が作れなくて困っているのですが、 .datのファイルから転置させるのが上手くできません。 《kadai1.datの3行4列の行列Aと、kadai2.datの4行3列行列Bがある。 行列A、行列B、行列Aの転置行列を出力し、 行列Aの転置行列と行列Bの和を出力するプログラムを作る。 kadai1.datとkadai2.datは自分で作る。》 で、途中まで作ったのが以下です。 #include <stdio.h> #include <stdlib.h> #define ROW   3 #define COLUMN 4 int main(void) { FILE *fp; double a[ROW][COLUMN], b[ROW][COLUMN]; int i, j; if ( ( fp = fopen( "kadai1.dat", "r" ) ) == NULL ) { printf("ファイルが見つかりません : kadai1.dat \n"); exit(1); } printf("行列Aは次の通りです\n"); for ( i = 0 ; j < COLUMN ; j++) { scanf (fp, "%lf", &a[i][j]); printf ("%5.2f\t", a[i][j]); } printf("\n"); } if ( ( fp = fopen( "kadai2.dat", "r" ) ) == NULL ) { printf("ファイルが見つかりません : kadai2.dat \n"); exit(1); } printf("行列Bは次の通りです\n"); for ( i = 0 ; j < COLUMN ; j++) { scanf (fp, "%lf", &a[i][j]); printf ("%5.2f\t", a[i][j]); } printf("\n"); } return 0; } \の半角が出なかったので¥になってます。 (ごめんなさい!!) 上のプログラムで、行列Aと行列Bが出力できたのですが、転置と和のプログラムが出来ていません。 kadai1.datが、 1 2 3 4 5 6 7 8 9 10 11 12 kadai2.datが、 13 14 15 16 17 18 19 20 21 22 23 24 にしてみました。a1 a2 … c3 c4、でやってる人もいるみたいですが具体的な数字で作ろうと思っています。 お手数おかけしますが具体的にお答えいただければ幸いです。 どうぞよろしくお願いいたします。

  • エクセルVBAで

    エクセルのVBAのFor文のような繰り返し処理で、 for i = 1 to 最終行 のように、セルA1からデータが入力されている最終行まで繰り返すために最終行を求めたいのですがどうすれば良いでしょうか?

  • Excel(VBA)マトリクスの解体方法について

    VBAで、以下のようなマクロを作成したいのですが、どのように作成したら良いのか検討がつきません。 どのようにすれば良いか、ご教授いただけたらと思います。 (過去の質問No.1488981を参考に記入させていただきます) (1)下記のように、縦横のマトリクス表にデータが入力されている。     A B C ・・ 1   X Y Z 2 a ○ × ○ 3 b × ○ ○ 4 c ○ ○ ○ (2)これを別シートに【"○"のついたデータのみ】縦に3列にデータを並べるように処理する。  左列には"項番"(1~)、中列には"行データ"、右列には"列データ" 1 a X 2 a Z 3 b Y 4 b Z  ・  ・  ・ (3)列データと行データの数は不定で、一番右下となるセルまで、処理を繰り返すかたちにする。(空白セルが10個以上になる等の条件で) 以上のような条件です。ご回答よろしくお願い致します。

専門家に質問してみよう