質問: エクセルマクロで質問です。 マクロを学びたいため、例のマクロを教えていただきたいです。 マンションのデータをまとめたいため、スーモのサイトからエクセルにコピペしました。 元データ ![イメージ説明](https://teratail-v2.storage.googleapis.com/uploads/contributed_images/57e01cefb9c1ce49065d1c4d216714a6.jpeg) この状態から sheet3のこれに整理していく ![イメージ説明](https://teratail-v2.storage.googleapis.com/uploads/contributed_images/96c63d2fc72607bf6afdea15490f9eb4.jpeg) やりたい条件としては、 ・A列を「チェック」で検索→ヒットしたセルの3個下のセルの内容をマンション名列に入れる ・販売価格で検索→ヒットしたセルのひとつ下のセルの内容を販売価格列に入れる ・・・・くりかえしです。 必要な項目だけを抜き出して整理するマクロを作りたいです。 よろしくお願いいたします。
回答: こんばんは。 サンプルのコードを書くにあたり、かなり決め打ちしている部分があり 期待した方法と異なるかもしれませんが、以下のコードではいかがでしょうか。 決め打ちしている事 ・データはSheet2に存在し、取得したデータはSheet3に出力する ・「チェック」が1固まりのデータの開始を示す(これは例の通りと思います) ・「チェック」は必ずA列に存在する ・取得対象の「間取り」と「築年月」はB列、それ以外はA列に存在する ・取得する情報(マンション名、販売価格など)はすべて「チェック」からの相対位置が同じ →項目毎に検索しないで、チェックからの相対位置を使って取得 ・スクリーンショットの通り、「チェック」から終端?「ロビー」までが30行なので データの1固まりは30行あるとする →コード中の「BLOCK_SIZE_ROW」がそれにあたります、30行より小さい可能性がある場合は 1固まりの最小となる行数を指定します 方法はいくらかあると思います。検索(Findコマンドなど)を使わないで、走査していく方が単純で 分かり易いと考えました。 # データの固まりと固まりの間に多くの空行が存在するような形でなければ、走査する方法であっても # そんなに効率は悪くないと思います。 ``` Option Explicit Sub Sample() Dim DataSht As Worksheet Dim PutSht As Worksheet Dim DataEndRow As Long Dim ReadRow As Long Dim ReadCol As Long Dim PutRow As Long 'データ走査開始位置 Const START_ROW = 1 Const START_COL = 1 'データ出力開始位置 Const PUT_START = 4 Const KEYWORD = "チェック" '各項目の「チェック」からの相対位置 Const MANSION_OFFSET_ROW = 3 'マンション名 Const MANSION_OFFSET_COL = 0 Const PRICE_OFFSET_ROW = 10 '販売価格 Const PRICE_OFFSET_COL = 0 Const LOCATION_OFFSET_ROW = 12 '所在地 Const LOCATION_OFFSET_COL = 0 Const STATION_OFFSET_ROW = 14 '沿線・駅 Const STATION_OFFSET_COL = 0 Const AREA_OFFSET_ROW = 16 '占有面積 Const AREA_OFFSET_COL = 0 Const FLOOR_OFFSET_ROW = 16 '間取り Const FLOOR_OFFSET_COL = 1 Const BUILT_OFFSET_ROW = 18 '築年月 Const BUILT_OFFSET_COL = 1 Const BLOCK_SIZE_ROW = 30 'データ1固まりの行数 Set DataSht = Sheet2 '元のデータが入っているシート Set PutSht = Sheet3 '取得した情報を出力するシート ' データの入っている最終行を取得(A列) DataEndRow = DataSht.Cells(Rows.Count, 1).End(xlUp).Row '走査開始位置で初期化 ReadRow = START_ROW ReadCol = START_COL '出力開始位置で初期化 PutRow = PUT_START Do While ReadRow < DataEndRow If DataSht.Cells(ReadRow, ReadCol).Text = KEYWORD Then With DataSht 'マンション名の取得 PutSht.Cells(PutRow, 1) = .Cells(ReadRow + MANSION_OFFSET_ROW, ReadCol + MANSION_OFFSET_COL).Text '販売価格の取得 PutSht.Cells(PutRow, 2) = .Cells(ReadRow + PRICE_OFFSET_ROW, ReadCol + PRICE_OFFSET_COL).Text '所在地の取得 PutSht.Cells(PutRow, 3) = .Cells(ReadRow + LOCATION_OFFSET_ROW, ReadCol + LOCATION_OFFSET_COL).Text '沿線・駅の取得 PutSht.Cells(PutRow, 4) = .Cells(ReadRow + STATION_OFFSET_ROW, ReadCol + STATION_OFFSET_COL).Text '占有面積の取得 PutSht.Cells(PutRow, 5) = .Cells(ReadRow + AREA_OFFSET_ROW, ReadCol + AREA_OFFSET_COL).Text '間取りの取得 PutSht.Cells(PutRow, 6) = .Cells(ReadRow + FLOOR_OFFSET_ROW, ReadCol + FLOOR_OFFSET_COL).Text '築年月の取得 PutSht.Cells(PutRow, 7) = .Cells(ReadRow + BUILT_OFFSET_ROW, ReadCol + BUILT_OFFSET_COL).Text End With ReadRow = ReadRow + BLOCK_SIZE_ROW PutRow = PutRow + 1 Else ReadRow = ReadRow + 1 End If Loop End Sub ```