質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
VBA

VBAはオブジェクト指向プログラミング言語のひとつで、マクロを作成によりExcelなどのOffice業務を自動化することができます。

マクロ

定義された処理手続きに応じて、どのような一連の処理を行うのかを特定させるルールをマクロと呼びます。

Q&A

解決済

2回答

3545閲覧

検索した文字から上のセルを検索して一致した最初の値を返してほしい

GKHHKJ

総合スコア39

VBA

VBAはオブジェクト指向プログラミング言語のひとつで、マクロを作成によりExcelなどのOffice業務を自動化することができます。

マクロ

定義された処理手続きに応じて、どのような一連の処理を行うのかを特定させるルールをマクロと呼びます。

0グッド

0クリップ

投稿2021/07/01 08:34

以下のようなシートがあります
”組織図”シート
(列 不特定
営業部
部付)田中太郎
部付)鈴木次郎
部付)佐藤三郎
部付)山田四郎

↑のシートから↓のシートのように転記したいです。

”Sheet1”
A列        B列
営業部      部付)田中太郎
営業部      部付)鈴木次郎
営業部      部付)佐藤三郎
営業部      部付)山田四郎

方法として、
"部付)"をFIND関数で検索、
B列にそれを転記
A列にその単語と同じ列で、その単語の上の行の中で“*部”検索して、
一番最初の値を返す

こんなマクロはどう組めばよろしいのでしょうか。

Sub 部付)検索() Dim SearchRange As Range '検索範囲格納 Dim ResultRange As Range '検索結果格納 Dim StartRange As Range '検索行格納 Dim KeyItem As String Set SearchRange = Worksheets("組織図").Range("A:Z") '検索したいデータ範囲 KeyItem = " 部付)" Set ResultRange = SearchRange.Find(KeyItem, Lookat:=xlPart) If Not ResultRange Is Nothing Then Set StartRange = ResultRange '最初に見つかったセルを格納しておく Do If InStr(ResultRange.Value, "プロジェクトチーム") = 0 Then ResultRange.Copy Worksheets("Sheet1").Cells(Rows.Count, 1).End(xlUp).Offset(1, 0).PasteSpecial (xlPasteValues) Application.CutCopyMode = False End If Set ResultRange = SearchRange.FindNext(After:=ResultRange) '次の検索セルを指定する If ResultRange.Address = StartRange.Address Then '見つかったセルが最初のセルか判定 Exit Do '同じ場合はループを離脱 End If Loop While StartRange <> ResultRange End If End Sub

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

相談者様のVBAコードを見ると、部付)から始まるセルを逐一検索し、1個ずつコピーしています。
CurrentRegionとResizeを活用すると、スッキリとしたコードになります。C列に社員データがある例
部門セルC1
開始セルC2
社員数4
社員セルC2:C5
を前提に、以下のコードを解説します。

Excel

1Option Explicit 2 3Sub 社員転記() 4 Dim startRange As Range ' "部付)"と書いてある最上位セル(以下開始セル) 5 Dim memberRange As Range ' 全社員が入っているセル(以下社員セル) 6 Dim member As Long ' 社員数 7 Dim department As String ' 部門名 8 9 ' "部付)"を含む文字列をA1セルを開始位置として部分一致検索 10 Set startRange = Cells.Find("部付)", lookat:=xlPart, after:=Range("A1")) 11 If startRange Is Nothing Then ' 見つからなかったらマクロ終了 12 Exit Sub 13 End If 14 15 ' 開始セルの一つ上のセルに入っている部門名を取り出す 16 department = startRange.Offset(-1, 0).Value 17 18 ' 開始セルを含む領域の行数-1(部門名のセルを除外)が社員数 19 member = startRange.CurrentRegion.Rows.Count - 1 20 21 '開始セルを社員数分だけ行方向に拡張したセル範囲が社員セル 22 Set memberRange = startRange.Resize(member, 1) 23 24 With Worksheets("sheet1") 25 memberRange.Copy .Range("B1") ' 社員セルを"B1"から始まるセルに転記 26 .Range("A1").Resize(member, 1) = department ' 部門名を"A1"から始まるセルに転記 27 End With 28End Sub

以下、重要な部分の説明

Find

  • 全範囲のセルはcellsとすればOK
  • 部分一致検索はLookat:=xlPart
  • 検索開始位置をAfter:="A1"とすれば、確実に一番上の社員を見つけられる。
  • この結果、図のC2セルが見つかる。

Offset

  • 開始セルから(行, 列)だけ移動したセルはstartRange.Offset(行, 列)で取得できる。

ここでは(行, 列) = (-1, 0)

CurrentRegion

  • CurrentRegionを使うと、該当セルを含む一続きの領域のセル範囲が得られる。

図の例ではRange("C2").CurrentRagionはRange("C1:C5")を表す。

  • 求めたセル範囲の行数-1で社員数が得られる(-1は部門名の行数を省くため)。

Resize

  • Resizeを使うと、セルの範囲を拡張できる。

図の例ではRange("C2").Resize(4, 1)でRange("C2:C5")を表す。

  • startRange.Resize(member, 1)で社員セル範囲が得られる。

あとは社員セルをSheet1のB1から始まるセルにコピーし、部門名をSheet1のA1から始まるセルにコピーする。

以上が回答となります。
お役に立てれば幸いです。

投稿2021/07/17 22:58

toitoburuku9

総合スコア19

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

こんな感じでどうでしょうか。

VBA

1Dim bu 2bu = ResultRange.End(xlUp).Value 3

投稿2021/07/01 12:05

jinoji

総合スコア4592

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問