• ベストアンサー

(excel VBA) データを一列にまとめる(マクロで一気に)

excel2003を使っています webページ全体を、テキスト形式でシートに貼り付けて その後必要な部分だけをマクロで抽出するという作業を行っています。 テキスト形式で貼り付けた際、ブックを開いた直後に(一度もマクロを実行してない状態)貼り付けを行うと、すべてのデータがうまくA列に貼り付けられるのですが、 一度マクロを実行させた後、同じように貼り付けを行うと、データがB列やC列に散らばってしまいます。(行の位置は変わりないです) この解決策が全く思いつかないので、次のマクロを組みました Range("A1").value = Range("A1").value & Range("B1").value まとめたい行が100行以上あるので、とりあえずDo~LoopかFor~nextを使って、この記述で1行ずつまとめていく感じです。ただ、一気に列全体をまとめれたほうがスピードが速いと思い、質問いたしました。 そこで (1)列全体を一気にまとめる方法はありますか? (2)そもそも貼り付けの段階で、ちゃんとA列にデータがまとまらないのはなぜ?(1回目はできるのに…) という質問に、お答えいただけないでしょうか? 質問を2つに分けようかとも思ったのですが、関連でしたので、まとめて質問させていただきました。 お力をお貸し願えないでしょうか?

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

  • ベストアンサー
  • KenKen_SP
  • ベストアンサー率62% (785/1258)
回答No.2

こんばんは。 > (1)列全体を一気にまとめる方法はありますか? ループで順次処理していくほかありません。処理速度が気になる のであれば、   Application.ScreenUpdating = False で画面更新を停止すれば良いかと。既存コードの提示がないので、 これ以上の具体的なアドバイスはしにくいです。 単純にテキストだけほしいなら、IE オブジェクトや HttpRequest オブジェクトから取得するという手もあります。 > (2)そもそも貼り付けの段階で、ちゃんとA列にデータがまとまらない > のはなぜ?(1回目はできるのに…) > 一度マクロを実行させた後、 このマクロの中で、「TextToColumns」メソッドを使っているの では? TextToColumns メソッドはテキストをある区切り文字でセルに 分解しますが、ここで行った区切り文字の設定はマクロ実行後も そのまま残ります。 コピー&ペーストの操作においても、この区切り文字の設定に 従ってセルに分解されますので、、 # 結局コードを提示しないと全て推測の回答しかできません。。 # なるべくコードを提示した方が良いと思います。

composer
質問者

お礼

TextToColumns メソッドはテキストをある区切り文字でセルに 分解しますが、ここで行った区切り文字の設定はマクロ実行後も そのまま残ります。 なるほどです。 この設定を元に戻すにはどうしたらいいですか?

composer
質問者

補足

確かにTextToColumns メソッドを使用しています。 コードは結構長いので、あえて提示しませんでした。 一部提示しますと Sub クチコミゲッター() Dim objSheet As Object Dim intLoop As Integer Dim copyLoop As Integer 'コピーデータの貼り付け Sheets("sheet1").Select Range("A1").Select ActiveSheet.PasteSpecial Format:="テキスト", _ Link:=False, _ DisplayAsIcon:=False '【質問の部分です。doLoopで処理しています】 copyLoop = 1 Do Range("A" & copyLoop).Value = Range("A" & copyLoop).Value & _ Range("B" & copyLoop).Value & _ Range("C" & copyLoop).Value & _ Range("D" & copyLoop).Value copyLoop = copyLoop + 1 Loop Until copyLoop = 150 '重複データ登録回避 Sheets("sheet2").Select If Range("D2").Value = 1 Then Sheets("sheet1").Select Columns("A:A").Select Selection.ClearContents MsgBox "データが重複しています、リストにはこの店舗は登録しません。", , "データの重複" Exit Sub Else Sheets("sheet1").Select '条件付書式の設定 Cells.Select Selection.FormatConditions.Delete Selection.FormatConditions.Add Type:=xlExpression, Formula1:= _ "=COUNTIF(A1,""予算*"")" Selection.FormatConditions(1).Interior.ColorIndex = 39 'リスト整理   L = 0 Range("A1:A4").Select Selection.Cut Range("B1").Offset(L, 0).Select ActiveSheet.Paste L = L + 4 Range("A28:A30").Select Selection.Cut Range("B1").Offset(L, 0).Select ActiveSheet.Paste L = L + 3 'クチコミ回収 Do Sheets("sheet2").Select Y = Range("B1").Value G = Range("B2").Value Sheets("sheet1").Select Range("A" & Y & ":A" & G).Select Selection.Cut Range("B1").Offset(L, 0).Select ActiveSheet.Paste L = L + G - Y Range("B1").Offset(L, 0).Select Selection.ClearContents Sheets("sheet2").Select L = L + 1 Loop Until Range("D1").Value = 0 '不要データ削除 Sheets("sheet1").Select Columns("A:A").Select Selection.ClearContents '店名抽出 Range("B1").Select Selection.TextToColumns Destination:=Range("B1"), DataType:=xlDelimited, _ TextQualifier:=xlNone, ConsecutiveDelimiter:=True, Tab:=False, Semicolon _ :=False, Comma:=False, Space:=True, Other:=True, OtherChar:="[", _ FieldInfo:=Array(Array(1, 1), Array(2, 1), Array(3, 9), Array(4, 9)), _ TrailingMinusNumbers:=True

その他の回答 (3)

  • KenKen_SP
  • ベストアンサー率62% (785/1258)
回答No.4

処理速度の低下要因としては、画面更新と数式(条件付書式)の 再計算でしょうね。 最大で 150 行程度ならこれらの停止で十分な速度が期待できます。 さらに高速化するとすれば、Select をなるべくしない書き方とか、 #1 ご回答にあるような配列処理などがありますが、今回は数量的に 言って、この程度で良い気がします。 Sub クチコミゲッター()   ' ~ 略 ~      ’メインの処理の前で   ' // 、画面更新と数式の再計算を停止   ' // コード実行中にエラーが発生した場合、エラーハンドラで   ' // メッセージを表示した後、Application の設定を元に戻す   On Error GoTo ERROR_HANDLER   With Application     .ScreenUpdating = False     .Calculation = xlCalculationManual   End With   ' ~ 中略 ~ ' // 終了処理 TERMINATE:   ' // TextToColumns の設定を元に戻す   ' // 適当なセルにダミーテキストを置いて初期状態の設定で   ' // TextToColumns メソッドを実行する(泥臭いかも^^;)      With Range("A1") ’<---空いている適当なセル     .Value = "RESTORE"     .TextToColumns DataType:=xlDelimited, _             TextQualifier:=xlDoubleQuote, _             ConsecutiveDelimiter:=False, _             Tab:=True, _             Semicolon:=False, _             Comma:=False, _             Space:=False, _             Other:=False, _             FieldInfo:=Array(1, 1), _             TrailingMinusNumbers:=True     .ClearContents   End With   ' // Application の設定を元に戻す   With Application     .ScreenUpdating = True     .Calculation = xlCalculationAutomatic   End With   Exit Sub    ' // エラーハンドラ ERROR_HANDLER:   MsgBox Err.Description, vbCritical   Resume TERMINATE ' // 終了処理へ飛ばす End Sub

composer
質問者

お礼

お礼とは異なるのですが、 マクロの途中で、sheet2のD2にあるCOUNTIF関数の値を所得して、その値が0になるまでDOループを続けるという記述があり、最初に .Calculation = xlCalculationManual にしておくと計算をしてくれず、ループを抜けることができません。 その場合、いちいち、ループの前後で .Calculationを変更しなければいけませんか?

composer
質問者

補足

1つ1つに丁寧な回答を頂き、大変感謝しています。 表示と再計算の問題ですが、確かに速度低下の原因はそこにあると思います。今のところデータの数が少なかったのと、時間的、能力的な問題で雑な記述が目立ちます。 表示に関しては、マクロの最初に Application.ScreenUpdating = False 最後に Application.ScreenUpdating = True を入れることでずいぶん高速化しました KenKen_SP様のように、自動計算についての記述を加えるとさらに高速化できると思います。 主にマクロの記録機能を使って独学でマクロを勉強していますので、こういったアドバイスは大変勉強になります。

  • Wendy02
  • ベストアンサー率57% (3570/6232)
回答No.3

こんばんは。 >(1)列全体を一気にまとめる方法はありますか? バラバラになったデータを一気にA列にまとめ上げるマクロ (おそらくは、空白値があるような気がしますから、数式の中を処理したほうがよいと思います) Sub TestSample1() Dim r As Range Set r = Range("A1", Range("A65536").End(xlUp))  '6列まで  r.Offset(, 6).FormulaLocal = "=TRIM(A1&"" ""&B1&"" ""&C1&"" ""&D1&"" ""&E1&"" ""&F1)"  r.Value = r.Offset(, 6).Value  ActiveSheet.UsedRange.Offset(, 1).ClearContents End Sub >(2)そもそも貼り付けの段階で、ちゃんとA列にデータがまとまらないのはなぜ?(1回目はできるのに…) >一度マクロを実行させた後、同じように貼り付けを行うと、データがB列やC列に散らばってしまいます。(行の位置は変わりないです) それは、区切り位置か、QueryTable を使っているのだと思いますから、ダミーデータを使って、もう一度、元の状態に戻してあげればよいと思います。以下の場合は、デフォルトに戻しています。(以上は、Excel2003のみでしか試験していません) Sub TestSample2()   With Range("A1")   .Select   .Insert xlShiftDown   .Offset(-1).Value = "AAA" 'ダミー   .TextToColumns _        Destination:=Range("A1"), _        DataType:=xlDelimited, _        TextQualifier:=xlDoubleQuote, _        ConsecutiveDelimiter:=False, _        Tab:=True, _        Semicolon:=False, _        Comma:=False, _        Space:=False, _        Other:=False, _        FieldInfo:=Array(1, 1), TrailingMinusNumbers:=True   .Delete xlShiftUp   End With    End Sub 私は、(2)のマクロは、似たような内容を個人用マクロブックに入れて使っています。

composer
質問者

補足

すばやい回答ありがとうございます NO.2様のご指摘どおり、マクロ内でTextToColumnを使っていました。 そこで、マクロの最後に '区切り位置の修正 Sheets("sheet2").Select Range("A1").Select Selection.TextToColumns Destination:=Range("A1"), DataType:=xlDelimited, _ TextQualifier:=xlNone, ConsecutiveDelimiter:=False, Tab:=False, _ Semicolon:=False, Comma:=False, Space:=False, Other:=False, FieldInfo _ :=Array(1, 1), TrailingMinusNumbers:=True という記述を追加し、対応するとうまくいきました。 Wendy02様の記述とどちらがよいかは当方では判断できませんので、ほぼ同じかな?と思っています。 (1)に関しては、(2)が解決するに及び、記述の必要が無くなったのですが、NO.2様の補足に記述したDOループよりもWendy02様の記述の方がいいように思います。今後同様の処理が必要になった際に参考にさせていただきます。ありがとうございました

  • merlionXX
  • ベストアンサー率48% (1930/4007)
回答No.1

(2)はわかりません。 (1)は、高速化ということですので、一旦配列に取り込んで処理したらいかがでしょう? A列と10列の100行目までを取り込み、A列に戻す例です。 Sub test001() Dim i As Long Dim ar As Variant Dim br(99, 0) ar = Range("A1:B100").Value For i = LBound(ar, 1) To UBound(ar, 1) br(i - 1, 0) = (ar(i, 1) & ar(i, 2)) Next Range("A1:A100").Value = br End Sub

関連するQ&A

  • 【Excelマクロ】 行全体を選択したい

    下記マクロはデータが入っている最終行の次のセル(A列)を選択するマクロです。 但し、A列はデータが入っていないこともあるため、必ずデータが入っているB列をキーにしています。 NT = Cells(Rows.Count, "B").End(xlUp).Row + 1 Range("A" & NT).Select B125までデータが入っていた場合A126にカーソルが置かれますが、本当は126行全体を選択したいのです。 「Range("A" & NT).Select」部分をどのようなマクロに変更したらよろしいでしょうか?

  • EXCEL2007マクロ/オートフィルについて

    VBA初心者です。 EXCEL2007でオートフィルのマクロを作ったのですが、下記のケースで困っています。 A列のデータが入っている行までB列のデータをオートフィルで入力したく、 A列の最終行からデータが入っている行までを求めてB列のデータをオートフィルで入れるため、下記のマクロを設定しました。 Sub test()   Range("B1").AutoFill Destination:=Range("B1", Range("A1048576").End(xlUp).Offset(, 1)) End Sub ところが、A列のデータが2行以上ある場合はうまくいくのですが、一行のみだった場合オートフィルができなくてマクロがとまってしまいます。 一行なので当然なのですが、このような処理をしたい場合、他に方法はないものでしょうか? お知恵を拝借できますと大変助かります。 どうぞよろしくお願いいたします。

  • EXCEL VBAマクロについて質問です

    Excel VBAマクロについて質問です ※Excel Ver.は2005でやってます 例のような感じで、 同じ列(列1)に或る同じ列名の数字(列2)を足して 違うセル、または違うブックの指定行に合計値を横並び表示させたいのですがうまくいきません 例のように 同じ言葉が含まれているもの(りんご・青りんご)は足して出したいと思ってます 【理想】実行前 ****************************** 番号  名前  個数 001   りんご  1 002   ばなな  2 003   いちご  3 001   青りんご 2 ****************************** 【理想】実行後 ****************************** 番号   りんご  ばなな  いちご 001    3      -     - 002    -      2     - 003    -      -      3 ****************************** ※「-」記号はついてなくても大丈夫です 現在、組んでいるコード・実行結果をのせておきました どなたか享受ください、お願いいたします j = 1 For i = 0 To Range("A65536").End(xlUp).Row cnt = cnt + Range("列2" & i).Value If Range("C" & i + 1).value <> Range("C" & i).value Then 'もし次の行が違う名 Range("任意セル" & j).Value = Range("A" & i).Value '列1 Range("任意セル" & j).Value = Range("B" & i).Value '列2 Range("任意セル" & j).Value = cnt '数字合計 j = j + 1 '出力行カウントアップ cnt = 0 End If Next

  • 重複行削除のマクロ

    重複行を削除するマクロを作っていますが、うまくいきません。 2行目にタイトルが入っていて、3行目以降が必要なデータになります。 この中でA列が一致しているデータ行を削除したいと考えており、 重複データが削除された後、タイトル行がなぜか一番下の行にはりついてしまいます。 どなたか詳しい方助けてください!!!よろしくお願いします。 ちなみに以下が現在使用しているVBAコードです。 =============================================================== Sub GoodRemoveDuplicates() 'A列にデータが入力されており、そのデータを並べ替えた後、 '重複するデータが含まれている行を削除するマクロ Worksheets("貼り付け用用マクロ").Range("A1").Sort _ key1:=Worksheets("貼り付け用用マクロ").Range("A1") Set currentCell = Worksheets("貼り付け用用マクロ").Range("A1") Do While Not IsEmpty(currentCell) Set nextCell = currentCell.Offset(1, 0) If nextCell.Value = currentCell.Value Then currentCell.EntireRow.Delete End If Set currentCell = nextCell Loop End Sub ===============================================================

  • Excelのマクロについて教えてください。

    Excelのマクロについて教えてください。 下記のマクロがあります。 With Range("A" & Rows.Count).End(xlUp) .EntireRow.Copy .Offset(1) .Offset(1).EntireRow.SpecialCells(xlCellTypeConstants).ClearContents .Offset(1).Value = .Value + 1 End With 実際にデータが入っているのはA列~E列までで .EntireRow(行全体)ではなく A?:E? と範囲を指定して上記を実行させたいのですが どのように変更するといいでしょうか。 よろしくお願いします。

  • Excel データ切り出しマクロについて

    Excelのマクロについてお聞きしたいと思います. たくさんあるテキストファイルの一部を切り取って貼り付けたい場合は どうしたらいいのでしょういか? マクロではない流れとしては テキストファイルを開く ↓ 全選択してコピー ↓ Excelに貼り付ける ↓ 必要な部分だけ切り取る ↓ 貼り付け データの例としては A 12.3 78.5 B 13.5 65.5 C 23.5 65.8 とあるとしたら一番右側の列のデータのみ(78.5,65.5,65.8) だけ必要とします(切り取りたい部分) どのようなマクロを組んだらいいのでしょうか? よろしくお願いいたします.. マクロ実行時にファイルを選択できる機能もつけていただけたら 嬉しいです. できましたら全コードを載せていただけたら幸いです.

  • マクロ:別ブックのデータの値を転記

    ExcelでVlook関数を使ってデータを検索していたのですが、マスタの件数(15,000件)と数式が多くなってしまいブックの容量が大きくなってしまって動きづらくなってしまったので、マスタと検索のブックに分け、マクロを使おうと思ってます。 簡単にいうと、 【マスタブック】   A列  B列 1  1   あ 2  2   い 【検索ブック】   A列  B列 1  2   い 2 検索ブックA列1行目に、「2」を入力してマクロを実行すると「い」が表示されるようにしたいのです。   開いておくのは検索ブックはのみです。 Sub 転記() Dim マスタ As Workbook Dim 検索 As Workbook Dim 行, 数字 As Long Dim Bname As String Bname = ActiveWorkbook.Name Workbooks.Open Filename:="C:\Documents and Settings\mi200274\デスクトップ\\マスタ.xls" Workbooks("マスタ.xls").Activate Set マスタ = Workbooks("マスタxls") Set 検索 = ThisWorkbook Set ws1 = マスタ.Worksheets("Sheet1") Set ws2 = 検索.Worksheets("Sheet1") On Error Resume Next 行 = 1 Do Until ws2.Range("A" & 行).Value = "" 数字 = ws2.Range("A" & 行).Value 対象 = ws1.Range("A:A").Find(数字, lookat:=xlWhole).Row ws2.Range("B" & 行).Value = ws1.Range("B" & 対象).Value 行 = 行 + 1 Loop ActiveWorkbook.Close Workbooks(Bname).Activate End Sub 以上のマクロを知人に教わりながら作ってみたのですが、マスタを一度開かないと検索はできないのでしょうか? 重たいデータなのでできれば開かずに検索して値を転記したいので、そのようなコマンド等ご存知の方教えてください。 ちなみにマクロは「新しいマクロの記録」から作る程度の初心者です。よろしくお願いします。

  • VBAマクロの文字列認識について

    立て続けの質問ですみません。 Data1 = 1 Data2 = "234567890123457890" Data = Data1 & Data2 Range("A1").Value = Data  上記のマクロを実行すると、A1カラムに"12345678901234567890"と文字列で表示されるはずなのですが、実際には"12345678901234500000"と表示されてしまいます。 A1カラムの書式設定はユーザー定義で"00000000000000000000"としています。 一方、下記のマクロを実行すると Data1 = 1 Data2 = "234567890123457890" Data3 = "x" Data = Data1 & Data2 & Data3 Range("A1").Value = Data "12345678901234567890x"と表示されます。これはどういう現象なのでしょうか?最初のマクロを実行すると右寄せになるので文字として認識されていないと思いますが、文字として認識させるやりかたが良くわかりません。T関数やTEXT関数を使ったりもしてみましたがどうもうまくいきません。 自分がやりたいのは、100桁以上もある数字と半角文字(カナ、アルファベット)混合の文字列を作って一行一データのCSVファイルを作りたいのですが、どうも数字の桁数が多いとうまくいかないことがわかってきたのですが・・・よろしくお願いします。

  • Excel2000のマクロで

    Excel2000のマクロで B1 AAA B2 B3 BBB B4 B5 CCC B6 B1~最後の行までで データがいくつ入ってるか知りたいのですが分かりません。 このときデータは3つ だから3を取りたいです。 それから A1に1 A3に2 A5に3 B列にデータが入ってる行に1から順に 数字を入れるにはどうしたらいいですか? 教えてください。よろしくお願いします。

  • エクセルでのマクロを使った参照

    教えてください。 シート1のB23:F73のデータをシート2に張りつけたいのですが、 その際にB列には連番で1~50の数字が入っており C、D列にはデータが有る場合とない場合があります。 データがある場合は必ず対で存在します。 貼り付けの際にC、D列にデータのある行のみ B、C、D列のデータを連続で並ばせたいのですが、 どのようにマクロを組んだらよろしいですか? 手元に資料もなく、困ってしまいました。 よろしくお願いします。 現在のマクロは以下の通りです Sub TEST4() Dim S1 As Worksheet, S2 As Worksheet Set S1 = Worksheets("SHEET1") Set S2 = Worksheets("SHEET1") S2.Range("A1:E51").Value = S1.Range("B23:F73").Value End Sub

専門家に質問してみよう