エクセルVBAで複数列のセル内改行位置でセルを分割する方法

このQ&Aのポイント
  • エクセルVBAを使用して、複数列にセル内改行がある場合に1改行を1行として分割する方法を教えてください。
  • 具体的には、A列には作業日があり、改行がある場合は1行として、改行がない場合はそのままの値を使用します。B列にも同様に終了日があります。どのように処理すれば良いでしょうか?
  • セル内改行がある場合には、改行ごとに新たな行を作成し、列ごとに対応する値を設定します。セル内改行がない場合には、そのままの値を使用します。このような処理をエクセルVBAで実現することができます。
回答を見る
  • ベストアンサー

複数列のセル内改行位置でセルを分割する方法

エクセルVBAで下記のように複数列にセル内改行があった時に 1改行を1行として分割をしたい場合、 【A列】 a1作業日(項目名) a2(改行あり) 2013/4/1 2013/4/3 a3(改行なし) 2013/4/1 a4(改行あり) 2013/4/1 2013/4/2 【B列】 b1終了日(項目名) b2(改行あり) 2013/4/2 2013/4/10 b3(改行なし) 2013/4/2 b4(改行あり) 2013/4/15 2013/4/20          ↓    A 列 B列    作業日 終了日 1行目 2013/4/1 2013/4/2 2行目 2013/4/3 2013/4/10 3行目 2013/4/1 2013/4/2 4行目 2013/4/11 2013/4/15 5行目 2013/4/16 2013/4/20 としたいとき、何か良い方法はありますでしょうか? よろしくお願いいたします。

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

  • ベストアンサー
  • cj_mover
  • ベストアンサー率76% (292/381)
回答No.7

' ' 注)セル内に無駄な改行がある場合はEmpty値と看做されます。 Sub Re8024419_3()   Const SMSG = "空白セルがあります。$このマクロは空白セルがある場合は機能しません。$" _         & " 空白セルに ""- 空 -"" を埋めて継続する場合は OK$" _         & " このまま終了する場合は キャンセル"   Dim mtxP, vTmp, v   Dim rngS As Range, rngP As Range, rngBlank As Range, r As Range   Dim tnRows As Long, tnCols As Long   Dim cnR As Long, cnLines As Long, cnLTmp As Long, cnC As Long   Dim i&, j&   Set rngS = Sheets("Sheet3").Range("A1").CurrentRegion ' シート名指定!   On Error Resume Next   Set rngBlank = rngS.SpecialCells(xlCellTypeBlanks)   On Error GoTo 0   If Not rngBlank Is Nothing Then     If MsgBox(Replace(SMSG, "$", vbLf), vbOKCancel + vbInformation + vbDefaultButton2) = vbOK Then       rngBlank.Value = "- 空 -"     Else       Exit Sub     End If   End If   Set rngP = Sheets.Add.Range("A1") ' = Sheet4.Range("A1") '   tnRows = rngS.Rows.Count   tnCols = rngS.Columns.Count   ReDim mtxP(1 To tnRows * 3, 1 To tnCols)   cnR = 1   cnC = 0   For Each r In rngS     cnC = cnC + 1     vTmp = r.Value     cnLines = 0     If InStr(vTmp, vbLf) > 0 Then       vTmp = Split(vTmp, vbLf)       For Each v In vTmp         mtxP(cnR + cnLines, cnC) = v         cnLines = cnLines + 1       Next     Else       cnLines = 1       mtxP(cnR, cnC) = vTmp     End If          If cnC = 1 Then       cnLTmp = cnLines     Else       If cnLines > cnLTmp Then cnLTmp = cnLines     End If     If cnC = tnCols Then       cnR = cnR + cnLTmp       cnC = 0     End If   Next   For i = 2 To cnR - 1     For j = 1 To tnCols       If IsEmpty(mtxP(i, j)) Then mtxP(i, j) = mtxP(i - 1, j)     Next j   Next i   rngP.Resize(cnR - 1, tnCols).Value = mtxP   Set rngS = Nothing:  Set rngP = Nothing End Sub

smanob55
質問者

お礼

非常に丁寧に対応していただきましてありがとうございました。自分の力だけではどうしようもなく、本当に助かりました。感謝感激です。

その他の回答 (6)

回答No.6

セル内の改行を直接処理し、数も2つ限定ではなく任意の数を想定しているので、ソコから先の位置合わせ、数合わせ、的なお仕事には、関知しません、、、 例えば、Max2個、下だけが欠けているとか、限定条件であれば、 最終フェーズのオマケ処理にあるような、空行削除みたいなやり方でのフォローは十分可能でヒョウ、、、 xLast = .UsedRange.Rows.Count For nn = xLast To (xHeads + 1) Step -1 If (Application.WorksheetFunction.CountA(.Rows(nn)) = 0) Then .Rows(nn).Delete End If Next

  • cj_mover
  • ベストアンサー率76% (292/381)
回答No.5

失礼、1ヶ所ミスりました。#4は破棄してください。 #元のシートの■!シート名を指定!■しないと動きません Sub Re8024419j()   Dim vTmp   Dim mtxP   Dim v   Dim rngS As Range   Dim rngP As Range   Dim rCol As Range   Dim r As Range   Dim cnRows As Long   Dim cnLines As Long   Dim cnTmp   Dim cnCols As Long   Set rngS = Sheets("シート名").Range("A2").CurrentRegion.Resize(, 2) ' ■!シート名を指定!■   Set rngP = Sheets.Add.Range("A:B")   ReDim mtxP(1 To rngS.Rows.Count * 3, 1 To 2)   cnRows = 1   For Each r In rngS     cnCols = r.Column     vTmp = r.Value     cnLines = 0     If InStr(vTmp, vbLf) > 0 Then       vTmp = Split(vTmp, vbLf)       For Each v In vTmp         mtxP(cnRows + cnLines, cnCols) = v         cnLines = cnLines + 1       Next     Else       cnLines = 1       mtxP(cnRows, cnCols) = vTmp     End If     If cnCols = 1 Then       cnTmp = cnLines     Else       If cnLines > cnTmp Then cnTmp = cnLines       cnRows = cnRows + cnTmp     End If   Next   rngP.Resize(cnRows-1).Value = mtxP   Set rngS = Nothing:  Set rngP = Nothing End Sub

smanob55
質問者

補足

何度も同じような質問をしてしまい申し訳ございません。 更に質問ですが、 開始日が2日(2行)あるのに対し、終了日が1日(1行)の場合、 対応者・終了日を開始日にあわせて2行それぞれに反映させる方法があれば教えてください。 ※現状、1セル2改行までとなっています。 よろしくお願いいたします。 【A列】 a1作業日(項目名) a2(改行あり) 2013/4/1 2013/4/3 a3(改行なし) 2013/4/1 a4(改行あり) 2013/4/1 2013/4/2 ※開始日は2日 【B列】 b1対応者(項目名) b2(改行あり) Aさん Bさん b3(改行なし) Cさん b4 Dさん(改行なし) 【C列】 c1終了日(項目名) c2(改行あり) 2013/4/2 2013/4/10 c3(改行なし) 2013/4/2 c4(改行なし) 2013/4/15 ※終了日は1日のみ          ↓    A 列 B列 C列 作業日 対応者 完了日 1行目 2013/4/1 Aさん 2013/4/2 2行目 2013/4/3 Bさん 2013/4/10 3行目 2013/4/1 Cさん 2013/4/2 4行目 2013/4/1 Dさん 2013/4/15※ 5行目 2013/4/2 Dさん 2013/4/15※ ※終了日は対応者が1人で1日ですが、2行に分割された際  2行ともに同一の人・終了日が反映される。

  • cj_mover
  • ベストアンサー率76% (292/381)
回答No.4

Sub Re8024419j()   Dim vTmp   Dim mtxP   Dim v   Dim rngS As Range   Dim rngP As Range   Dim rCol As Range   Dim r As Range   Dim cnRows As Long   Dim cnLines As Long   Dim cnTmp   Dim cnCols As Long   Set rngS = Sheets("シート名").Range("A2").CurrentRegion.Resize(, 2) ' ■!適宜指定!■ ' シート名   Set rngP = Sheets.Add.Range("A:B")   ReDim mtxP(1 To rngS.Rows.Count * 3, 1 To 2)   cnRows = 1   For Each r In rngS     cnCols = r.Column     vTmp = r.Value     cnLines = 0     If InStr(vTmp, vbLf) > 0 Then       vTmp = Split(vTmp, vbLf)       For Each v In vTmp         mtxP(cnRows + cnLines, cnCols) = v         cnLines = cnLines + 1       Next     Else       cnLines = 1       mtxP(cnRows, cnCols) = vTmp     End If     If cnCols = 1 Then       cnTmp = cnLines     Else       If cnTmp > cnLines Then cnTmp = cnLines       cnRows = cnRows + cnTmp     End If   Next   rngP.Resize(cnRows-1).Value = mtxP   Set rngS = Nothing:  Set rngP = Nothing End Sub

回答No.3

Option Explicit Sub セルを改行で分割() Const xName = "Sheet119" '出力シート名 Const xCol_From = 1 '処理対象列番号(From) Const xCol_To = 2 '処理対象列番号(To) Const xHeads = 1 'ヘッダ(見出し)行数 Dim xSheet As Worksheet Dim xPart As Variant Dim xLast As Long Dim xRow As Long Dim jj As Long Dim kk As Long Dim mm As Long Dim nn As Long Application.ScreenUpdating = False Application.DisplayAlerts = False On Error Resume Next Set xSheet = ActiveSheet Worksheets(xName).Delete Worksheets.Add After:=Worksheets(Worksheets.Count) Worksheets(Worksheets.Count).Name = xName With Worksheets(xName) Application.CutCopyMode = False xSheet.Rows(1).Resize(xHeads).Copy .Rows(1).PasteSpecial 'xLast = xSheet.Cells(Rows.Count, "A").End(xlUp).Row xLast = xSheet.UsedRange.Rows.Count For nn = (xHeads + 1) To xLast Application.CutCopyMode = False mm = .UsedRange.Rows.Count + 1 xSheet.Rows(nn).Copy .Cells(mm, "A").PasteSpecial xRow = mm For kk = xCol_From To xCol_To mm = xRow xPart = Split(xSheet.Cells(nn, kk).Value, vbLf) If (UBound(xPart) > 0) Then For jj = 0 To UBound(xPart) .Cells(mm, kk).Value = Application.WorksheetFunction.Clean(xPart(jj)) Debug.Print .Cells(mm, kk).Address & ":" & .Cells(mm, kk).Value & ":" & jj & "/" & UBound(xPart) mm = mm + 1 Next Else ' .Cells(mm, kk).Value = xSheet.Cells(nn, kk).Value End If Next Next xLast = .UsedRange.Rows.Count For nn = xLast To (xHeads + 1) Step -1 If (Application.WorksheetFunction.CountA(.Rows(nn)) = 0) Then .Rows(nn).Delete End If Next xLast = .UsedRange.Rows.Count .Rows((xHeads + 1) & ":" & xLast).AutoFit End With Application.CutCopyMode = False Application.DisplayAlerts = True Application.ScreenUpdating = True End Sub

smanob55
質問者

補足

1度に質問せずに申し訳ございません。 更に質問ですが、 開始日が2日(2行)あるのに対し、終了日が1日(1行)の場合、終了日を開始日にあわせて2行それぞれに反映させる方法があれば教えてください。 よろしくお願いいたします。 【A列】 a1作業日(項目名) a2(改行あり) 2013/4/1 2013/4/3 a3(改行なし) 2013/4/1 a4(改行あり) 2013/4/1 2013/4/2 ※開始日は2日 【B列】 b1終了日(項目名) b2(改行あり) 2013/4/2 2013/4/10 b3(改行なし) 2013/4/2 b4(改行なし) 2013/4/15 ※終了日は1日のみ          ↓    A 列 B列    作業日 終了日 1行目 2013/4/1 2013/4/2 2行目 2013/4/3 2013/4/10 3行目 2013/4/1 2013/4/2 4行目 2013/4/11 2013/4/15※ 5行目 2013/4/16 2013/4/15※ ※終了日が1日ですが、2行に分割された際  2行ともに同一の終了日が反映される。

  • keithin
  • ベストアンサー率66% (5278/7940)
回答No.2

割とベタな手で。 Sub macro1()  Dim c As Long  Dim r As Long  Dim d()  Dim x  For c = 1 To Range("IV1").End(xlToLeft).Column   ReDim d(0)   d(0) = Cells(1, c)   For r = 2 To Cells(65536, c).End(xlUp).Row    For Each x In Split(Cells(r, c), vbLf)    ’要素を1つずつ配列に拾っていく     ReDim Preserve d(UBound(d) + 1)     d(UBound(d)) = x    Next   Next r   Cells(1, c).Resize(UBound(d) + 1, 1) = Application.Transpose(d)  Next c End Sub

  • cj_mover
  • ベストアンサー率76% (292/381)
回答No.1

こんにちは。 For Each ... Next ループで統一してみました。 一応、各列の行数に不整合があったりしても各列でコンプリートします。 動作確認できたら  Application.ScreenUpdating = False など、自信のある範囲で追記してみるのもアリと思います。 Sub Re8024419c()   Dim vTmp ' ソースのセル範囲、各セルの値、または値配列   Dim v ' 配列変数の各値   Dim rngS As Range ' ソースのセル範囲   Dim rngP As Range ' 出力先のセル範囲(左上のセルのみ参照)   Dim rCol As Range ' ソースのセル範囲、各列   Dim r As Range ' ソースのセル範囲、各セル   Dim cnRows As Long ' 出力先のセル、相対的行位置   Dim cnCols As Long ' 出力先のセル、相対的列位置      Set rngS = Range("A1:B6") ' ■!適宜指定!■ ' ソース   Set rngP = Range("D1") ' ■!適宜指定!■ ' 出力先   cnCols = 0 ' '   Application.ScreenUpdating = False   For Each rCol In rngS.Columns     cnCols = cnCols + 1 ' 出力先の列をカウント     cnRows = 0     For Each r In rCol.Cells       vTmp = r.Value       If InStr(vTmp, vbLf) > 0 Then ' セル内改行が見つかれば         vTmp = Split(vTmp, vbLf) ' セル内改行を区切り文字にした配列         For Each v In vTmp           cnRows = cnRows + 1 ' 出力先の行をカウント           rngP(cnRows, cnCols) = v ' 出力         Next       Else         cnRows = cnRows + 1 ' 出力先の行をカウント         rngP(cnRows, cnCols) = vTmp ' 出力       End If     Next r   Next   Set rngS = Nothing:  Set rngP = Nothing End Sub

関連するQ&A

  • セル内で改行された文字列をセル分割したい

    以下のような一セル内で改行された文字列を改行ごとに分割して別シートへコピーするExcelVBAを作成したいと考えています。 (以下は山田さんのレコード一行を記載しましたが下のセルに担当者のレコードが同様に続きます。)    A         B           C          D  ----------+---------------+------------+---------------+   担当者      日付         履歴        更新日  ----------+---------------+------------+---------------+  山田       2001/01/01    札幌支店    2005/01/01            2002/01/01    福岡支店    2005/04/01            2003/04/01    東京支店    2005/04/01  ----------+---------------+------------+---------------+ 上記を別シートへ以下のようにセル内容を分割してコピーしたいのです。    A         B            C           D  ----------+---------------+------------+---------------+   担当者     日付         履歴       更新日  ----------+---------------+------------+---------------+    山田     2001/01/01    札幌支店     2005/01/01  ----------+---------------+------------+---------------+    山田     2002/01/01    福岡支店     2005/04/01  ----------+---------------+------------+---------------+    山田     2003/04/01    東京支店     2005/04/01  ----------+---------------+------------+---------------+ ※質問の表記で-------------+-----------と記載しているのは セルをイメージしました。A1に「担当者」A2に「山田」と記載しているイメージです。問題はB.C.D列のセル内容ですが前任者が一つのセルに改行を利用して入力しているため、内容を行に分割したいと考えています。件数が非常に多く手作業を排除した方法でVBAを利用した方法がわかる方にお教えいただきたく投稿させていただきました。 当方Excel2000を利用していますが上記の処理VBAマクロをどうか教えてください。

  • Excel マクロ VBA セル内で改行された文字列の分割

    はじめまして。 ExcelのVBA初心者で、ちょっと困っています。 (例) (1) セルA1に以下のような改行された文字列が入力されています。 【セルA1】 a aa aaa b bb bbb (2) セルA1内の文字列を3行毎に分割し、セルA2以降に表示させたい。 【セルA2】 a aa aaa 【セルA3】 b bb bbb ※ 今回の例ではセルA1に6行しかありませんが、実際に行数は決まっていません。 そこで以下のようなVBAを見よう見まねで作り、1行毎の分割はうまくいったのですが、『3行毎に分割』ができません。 Sub 分割() Dim A, B, C A = Split(Range("A1"), Chr(10)) B = 0 For Each C In A B = B + 1 Range("A2").Offset(B - 1, 0).Value = C Next End Sub ご教授いただけると助かります。 よろしくお願い致します。

  • 一つのセルにあるデータを項目別に複数列に分割したい

    一つのセルにあるデータを項目別に複数列に分割したいです。 初歩な質問かも知れませんが教えて下さい。Excel 2010使用です。 一つのセルに「」に囲まれた項目別のデータが全て詰まっています。「」に囲まれた複数の文字列は項目名が書かれているのですが、これを分割し、列の先頭に項目名を付けて分割したいです。A2のセルから1列にデータが入っており、セル内にある項目は「郵便番号」「住所」「氏名」「電話番号」「誕生日」「血液型」。 これを分割していきたいのですが、必ずしも全てのデータが入っているわけではなく、データが欠けているものがあります。添付の2行目のような結果を出す関数やマクロなど、わかりましたらご教授いただけないでしょうか・・・。(画像が小さいため、A列とB~G列と分割しました。わかりづらくスミマセン。) たくさん調べたのですが、なかなか当てはまるものが見つからず、お力を貸してください。。

  • セル内で改行された文字列をセル分割したい

    以下のような一セル内で改行された文字列を改行ごとに分割して別シートへコピーしたいと考えています。 (以下は山田さんのレコード一行を記載しましたが下のセルに担当者のレコードが同様に続きます。)    A         B           C          D  ----------+---------------+------------+---------------+   担当者      日付         履歴        更新日  ----------+---------------+------------+---------------+  山田       2001/01/01    札幌支店    2005/01/01            2002/01/01    福岡支店    2005/04/01            2003/04/01    東京支店    2005/04/01  ----------+---------------+------------+---------------+ 上記を別シートへ以下のようにセル内容を分割してコピーしたいのです。    A         B            C           D  ----------+---------------+------------+---------------+   担当者     日付         履歴       更新日  ----------+---------------+------------+---------------+    山田     2001/01/01    札幌支店     2005/01/01  ----------+---------------+------------+---------------+    山田     2002/01/01    福岡支店     2005/04/01  ----------+---------------+------------+---------------+    山田     2003/04/01    東京支店     2005/04/01  ----------+---------------+------------+---------------+ 当方Excel2000を利用していますが上記の処理VBAマクロをどうか教えてください。

  • セル内の改行された文字列を分割

    初めて質問します。 添付画像のようにセル内の改行された文字列を学校名1、2、3・・・といったように分割をするにはどうすればいいのでしょうか。 ちなみにデータには改行されていない(学校名が一つだけ)のデータもあります。 よろしくお願い致します。

  • エクセルVBAで、複数セルのデータをひとつのセルに改行してまとめたいのですか・・・

    データの内容をひとつのセルに改行して入れていくという 作業を自動化できないでしょうか? 「データ」シート メモ 地点 from ~ to 線種 A1,B1,C1,D1,E1,F1に上の項目があり、 メモ、地点には文字、from ~ toには時刻(00:00)が入り、線種には =====というような記号が入ります。("~"の列には00:00形式の時刻が入る他"~"という記号が入るときもあります) それぞれの項目の下にデータを入力してあります。 これを「まとめ」シートに ・A~E列までをひとつのセルに改行してまとめる ・F列はその右隣にそのまま表記する と自動でできないかと考えています。例えば、「データ」2行目に A2 観劇 B2 日本大劇場 C2 10:00 D2 ~ E2 12:00 F2 ====== とある場合、「まとめ」シート A2セルは 観劇 日本大劇場 10:00~12:00 と改行して入り、B2に「データ」F2の======が入るように「データ」シートのデータがなくなるまで右にずらっとつなげていくようにしたいと思っています。今手作業でやっているのですが時間がかかって・・・。 よろしくお願いします。

  • Excelセル内の改行を含む文字列の1行目抽出

    Excelセル内の改行を含む文字列があり、関数を使って、その1行目だけ抽出したい。 たとえば、下記のような式を書きました。「改行コード」おかしみたいで動作しません。 Left("A1", Find(vbCrLf, "A1")) (改行コードをさがして、そこまでの文字列を切り取る) これをVBAで書く方法があれば、コードを教えてください!

  • エクセル セル内改行を別セル抽出

    画像のように、セル内で改行された文字を別のセルに分割して抽出したいのですが、どうしたらいいものでしょう。 一気には無理でも、できるだけ簡単に、早く、という感じで。 複数行、複数列が対象です。 区切り位置とかで試してみたのですが、一列一列しか処理できないことや、違う列に上書きされたりして、結構時間がかかるもので。 すいません、何卒よろしくお願いいたします!

  • エクセル 行数指定し一つのセルに改行込で入れる

    日本語が下手でもうしわけないです。 エクセルのマクロにて、行数指定指定したセルを別セルに 改行を含めて入れたいのです。 具体的なやりたいこととしては、 A列に不定期間隔で不定形の文字列が入力されていて、(間は空白) その文字列から文字列の行数を読み、 B列の同じ行数分のセルをひとまとまりとし、 別シートのA1に改行込みで入れる。 次のまとまりはA2に次はA3に… といった動作をさせたいです。 例. 1.A1,A6,A9に文字列があるとする。間は空白 文字列間の行数を読む (1)A1-A5 (2)A6-A8 (3)A9-最終行 2.A列で取得した行数と同じ行数をB列で指定 (1)B1-B5 (2)B6-B8 (3)B9-最終行 3.B列で指定したセルをひとまとまりとして 別シートのA1から順に改行込みで入れる (1)シート2のA1 B1(改行) B2(改行) B3(改行) B4(改行) B5(改行) (2)シート2のA2 B6(改行) B7(改行) B8(改行) (3)シート2のA3 B9(改行) ・ ・ 最終行 ####### マクロでの実現を考えているのですが、 マクロ初心者でさっぱりわかりません。 どなたか、マクロでの記述例を教えて頂けないでしょうか。 また、関数で実現できるのであれば、そちらも教えて頂きたいです。 宜しくお願いします。

  • エクセルVBA 文字列複数行・列連続連結

    エクセルVBA 文字列複数行・列連続連結でお教え下さい A列に基本文字(縦順) B列~F列に複数行データー(文字・時間) 文字結合時に改行 例 A2&B2&改行&A3&C2&改行&A4&D2&改行・・・・・ 次のデーター行 A&B3&改行&A3&C3&改行&A4&D3&改行・・・・・ データーの最終行まで連続で このような複数行あるデーターの連続文字列連結をしたいのですが・・・ 文字列連結後は 1.指定セルに貼り付け 2.クリップボードに貼り付け 3.テキストファイルに保存 よろしくお願い致します

専門家に質問してみよう