雑誌バックナンバー検索の条件判断と抽出実行のVBA

zassibackno02eyecatchaaa

エクセルVBA バックナンバー検索のデータベースを検索するマクロを作成します。

何を検索キーにするかは重要です。ここでは雑誌名・雑誌コード・期間をキーにします。

こんにちは、じゅんぱ店長(@junpa33)です。

先回に引き続き、「雑誌バックナンバー検索ツール」を作成していきます。

今回は、検索条件からマッチしたデータを抽出、検索結果として作表し表示させるところになります。

検索条件の項目を設定

backnoken2006kai

まず最初にどういった項目をキーにして検索を行うかを決めておきます。

普通に、業務上で良く調べる項目の”雑誌名”・”雑誌コード”を検索項目とします。

検索対象データの期間については、使用する送品データの期間に依存しますが、その中で更に期間を絞り込んで検索できるように”検索期間”を副項目キーとして設定できるようにします。

例えば

複数年分の送品データを、バックナンバー検索のデータベースとしたとして、

副項目キーの”検索期間”を設定することで、”雑誌名”・”雑誌コード”の検索条件を、

  • 単年分だけに絞り込み
  • 単年度の何ヶ月かの期間
  • 単年度の何ヶ月かの期間の何日かの期間
  • 複数年で同じ何ヶ月の期間(対比)
  • 複数年で同じ何ヶ月の期間の何日かの期間(対比)など

条件付き検索の幅が大きく広がることになります。

このように、検索項目を、”検索期間”・”雑誌名”・”雑誌コード”として進めていきます。

検索条件判断と実行のVBAコード組み

backnoken2007kai

VBAのコード組み立てはこのように計画します。コードは ”Module2” に記述します。

雑誌名での検索VBA

検索条件 ” 雑誌名 ” のコード設計は、送品データベース全期間で該当する ” 雑誌名 ” を抽出し、更に ” 検索期間 ” での絞り込みを行います。

雑誌コードでの検索VBA

検索条件 ” 雑誌コード ” のコード設計は、送品データベース全期間で該当する ” 雑誌コード ” を抽出し、更に ” 検索期間 ” での絞り込みを行います。

” 検索期間 ” を部品化コードとし、 ” 雑誌名 ” と ” 雑誌コード ” をそれぞれ別のプロシージャーとして作成します。

変数宣言セクション

次回の記事内容になりますが、検索条件の入力方法はユーザーフォームを利用するようになります。そのユーザーフォームで取得した検索値は異なるモジュールで取得しますので、ここ(Module2)で利用するためには、宣言セクションで記述します。

スコープ(適用範囲)をすべてのモジュールでで使える「パブリック変数」とします。

VBA
Option Explicit
    Public fdatey As Variant
    Public tdatey As Variant
    Public fdatem As Variant
    Public tdatem As Variant
    Public fdated As Variant
    Public tdated As Variant
    Public myKEY As Variant
    Public myKEYb As Variant
    Public Krow As Long
    Public Drow As Long
    Dim Y As Long
    Dim M As Long
    Dim D As Long
    Dim Check As String

雑誌名での検索VBA

雑誌名での検索VBAの全コードです。

検索のためのコードを組み立てるには、FindとFindNextメソッドを利用します。

VBA
Sub 雑誌名検索()
    Dim Tc As Range
    Dim Tcs As Range
    Dim myRange As Range
    Dim Frow As Long
    Dim i , n , H As Long
        Call Module2.検索結果クリア
'検索結果シートに見出しを貼り付け
        With Worksheets("データまとめ")
            .Range("A1", "L1").Copy _
                    Destination:=Worksheets("検索結果").Range("A1")
            .Select
            Drow = .Range("B1").CurrentRegion.Rows.Count
        End With
        Set myRange = Range("I2", "I" & Drow)
'雑誌名を検索
        H = 2
        Set Tc = myRange.Find(myKEY, LookIn:=xlValues, _
                            LookAt:=xlPart, MatchByte:=False)
        If Tc Is Nothing Then
            Worksheets("検索結果").Select
            MsgBox "「" & myKEY & "」はありませんでした", vbExclamation, _
                        "バックナンバー検索"
            Exit Sub
            Call Module2.検索結果クリア
        End If
        Frow = Tc.Row
        Set Tcs = Tc
        Do
            Worksheets("データまとめ") _
                .Range("A" & Tcs.Row, "L" & Tcs.Row).Copy _
                    Destination:=Worksheets("検索結果").Range("A" & H)
            Set Tcs = myRange.FindNext(Tcs)
            If Tcs Is Nothing Then Exit Do
            H = H + 1
        Loop Until Tcs.Row = Frow
'検索結果を一旦整理
        Worksheets("検索結果").Select
        Krow = Range("B1").CurrentRegion.Rows.Count
        n = 1
        For i = 2 To Krow
            Range("A" & i) = n
            n = n + 1
        Next i
'期間設定条件を加味する
        Call Module2.期間設定
        Application.CutCopyMode = False
        Call Module1.シート体裁
                If Worksheets("検索結果").Range("B2") = "" Then
            MsgBox "該当する検索結果はありません。", vbExclamation, _
                        "バックナンバー検索"
        Else
            MsgBox "検索結果を表示しました。", vbInformation, _
                        "バックナンバー検索"
        End If
End Sub

検索結果シートに見出しを貼り付け

データまとめシートの1行目の見出しをそのまま検索結果シートにコピペします。

雑誌名を検索

Findメソッド、FindNextメソッドを使って雑誌名の検索キーで存在を調べ、見つけたデータを検索結果シートにコピペします。文字の部分一致で検索することが出来ます。

検索結果を一旦整理

検索結果に取り出した検索データを、一旦整理します。

A列にID番号を割り振ります。

期間設定条件を加味する

抽出した検索結果をさらに、期間条件設定で絞り込みを行います。部品化した期間設定プロシージャーを呼び出します。

その後、検索結果シートの体裁を整えて終了します。

雑誌コードでの検索VBA

雑誌コードでの検索VBAの全コードです。

雑誌名での検索と同様に、コードを組み立てるには、FindとFindNextメソッドを利用します。

VBA
Sub 雑誌NO検索()
    Dim Tcb As Range
    Dim Tcsb As Range
    Dim myRangeb As Range
    Dim Frowb As Long
    Dim i As Long, n As Long
        Call Module2.検索結果クリア
'検索結果シートに見出しを貼り付け
        With Worksheets("データまとめ")
            .Range("A1", "L1").Copy _
                Destination:=Worksheets("検索結果").Range("A1")
            .Select
            Drow = .Range("B1").CurrentRegion.Rows.Count
        End With
        Set myRangeb = Range("D2", "D" & Drow)
'雑誌コードを検索
        H = 2
        Set Tcb = myRangeb.Find(myKEYb, LookIn:=xlValues, _
                                LookAt:=xlWhole, MatchByte:=False)
        If Tcb Is Nothing Then
            Worksheets("検索結果").Select
            MsgBox "「" & myKEYb & "」はありませんでした", vbExclamation, _
                        "バックナンバー検索"
            Exit Sub
            Call Module2.検索結果クリア
        End If
        Frowb = Tcb.Row
        Set Tcsb = Tcb
        Do
            Worksheets("データまとめ") _
                .Range("A" & Tcsb.Row, "L" & Tcsb.Row).Copy _
                    Destination:=Worksheets("検索結果").Range("A" & H)
            Set Tcsb = myRangeb.FindNext(Tcsb)
            If Tcsb Is Nothing Then Exit Do
            H = H + 1
        Loop Until Tcsb.Row = Frowb
'検索結果を一旦整理
        Worksheets("検索結果").Select
        Krow = Range("B1").CurrentRegion.Rows.Count
        n = 1
        For i = 2 To Krow
            Range("A" & i) = n
            n = n + 1
        Next i
'期間設定条件を加味する
        Call Module2.期間設定
        Application.CutCopyMode = False
        Call Module1.シート体裁
        If Worksheets("検索結果").Range("B2") = "" Then
            MsgBox "該当する検索結果はありません。", vbExclamation, _
                        "バックナンバー検索"
        Else
            MsgBox "検索結果を表示しました。", vbInformation, _
                        "バックナンバー検索"
        End If
End Sub

雑誌名での検索の場合とほぼ同じコード構成になっています。

検索のターゲット列が違うだけでやっていることが雑誌名と同じなので、もっと記述文字量を減らせるようにも出来ますが、敢えて同様のコードを検索キー別に記述しています。

理由は少しでもメンテを分かりやすくするためです。(メンテ時のVBAコード再読が面倒だからです。)

コードの内容は、先の雑誌名のVBAを見てください。

期間設定の検索VBA

雑誌名での検索結果、あるいは、雑誌コードでの検索結果が出た後で、検索対象期間が設定されている場合は、更にその期間で結果の絞り込みを行います。

期間絞り込みの方法

検索結果データの中から「この期間だけ」という絞り込み方法は結構難いです。

何年何月何日~何年何月何日まで...というだけでなく、年度に関係なく何月何日~何月何日とか、何日~何日なんていう絞り込みもあるからです。

なので、パラメーターになる年・月・日の開始と終了 合計6つのパラメーターを個別に期間対象内か対象外かを判断します。

期間対象外については、その都度データ削除するのではなく(その都度削除していけば、1処理毎に行番号が変化してデータ位置がズレてしまう)、期間対象外マーク「●」をデータに付けていきます。

そして全部の検索結果データをチェックした後で、「●」マークのデータを一挙に削除します。

VBA
Sub 期間設定()

    Dim Krowc As Long
    Dim i As Long, j As Long, p As Long
'期間設定がされていない場合はスキップ
        If fdatey = "" And fdatem = "" And fdated = "" Then Exit Sub
'対象期間外にチェックマークする
        For j = 2 To Krow
            Y = Left(Range("B" & j), 4)
            M = Mid(Range("B" & j), 5, 2)
            D = Mid(Range("B" & j), 7, 2)
            Worksheets("検索結果").Activate
    '部品化プロシージャーを呼び出し
            Call Module2.Check期間
            If Check = "NO" Then Range("A" & j) = "●"
        Next j
'対象期間外データを削除
        Call Module2.●削除
        With Worksheets("検索結果")
            .Range("A1").CurrentRegion.Sort key1:=.Range("B2"), _
                                Header:=xlYes
        End With
'対象内データを整理・体裁を整える
        Krowc = Range("B1").CurrentRegion.Rows.Count
        p = 1
        For i = 2 To Krowc
            Range("A" & i) = p
            p = p + 1
        Next i
        Call Module1.シート体裁
End Sub

期間設定がされていない場合はスキップ

期間設定がなされていない検索は、このプログラムは必要ないので早々に離脱します。

対象期間外にチェックマークする

6条件を一つずつ比較していますが、その時の対象外のデータについては対象外マークをスタンプしていきます。(”●”を付けます。)

送品データの送品年月日8桁を「年」「月」「日」に分解します。

部品化プロシージャー「Check期間」を呼び出します。

Check期間プロシージャー

VBA
Sub Check期間()
    Dim flga, flgb, flgc As Boolean
'変数の初期化
        flga = False
        flgb = False
        flgc = False
        Check = "YES"
        flga = (Y >= fdatey And Y <= tdatey)
        flgb = (M >= fdatem And M <= tdatem)
        flgc = (D >= fdated And D <= tdated)
'検索期間設定が空欄の時の対処
        If fdatey = "" Then flga = True
        If fdatem = "" Then flgb = True
        If fdated = "" Then flgc = True
'チェックマークの判定
        If (flga And flgb And flgc) = False Then
            Check = "NO"
        End If
End Sub
対象期間判定の方法

各送品データには必ず送品日付があります。送品日付けを「年」「月」「日」に分解して個別に期間対象かどうかを判定します。

1つの送品データで「年」「月」「日」すべてが対象内の場合は「OK」で、うち1つの項目でも対象外の場合は「NG」になります。

つまり、『「年」がOK かつ「月」がOK かつ「日」がOK 』以外はNGとしてチェックマーク「●」を付けます。

「年」「月」「日」の中で未入力の項目については、「強制的にOK」としてスルーします。

サンプル

「ザテレビジョン」を検索、検索期日を 年を「2022~2022」月を「4~4」日を「07~14」に設定しました。

backnoken2009kai

対象期間外データを削除

部品プロシージャーとして作成してある、「●削除プロシージャー」を呼び出します。

削除後、B列をキーにして昇順並び替えを行ないます。

●削除プロシージャー

チェックした期間外検索結果データの削除は「●」を目印にして、

同一データ重複削除メソッド「RemoveDuplicates」を使って一挙に1つに減らしてしまいます。

最後に残りの1つの”●”のセル位置を特定して行削除すればOKということです。

この方法は、不注意コードによる、削除の行ズレを防止するのにとても有効です。

VBA
Sub ●削除()
    Dim Krow As Long
    Dim Krowb As Long
    Dim n As Long
        Krow = Range("B1").CurrentRegion.Rows.Count
        Range("A2:L" & Krow).RemoveDuplicates (Array(1))
        Krowb = Range("B1").CurrentRegion.Rows.Count
        For n = 2 To Krowb
            If Range("A" & n) = "●" Then
                Rows(n).Delete
            End If
        Next n
End Sub

サンプル

チェックマークのデータを削除、IDを再設定しました。

backnoken2010kai

対象内データを整理・体裁を整える

検索期間を加味した検索結果データを作表整理整頓して仕上げます。

検索結果のクリア

次の検索作業をするときのために、前の検索結果をクリアします。

  • 全セルを掴んでClearメソッド
  • セルのUseStandardプロパティ
VBA
Sub 検索結果クリア()
    Dim mb As Workbook
        Set mb = ThisWorkbook
        With mb.Worksheets("検索結果")
            .Select
            .Cells.Clear
            .Cells.UseStandardHeight = True
            .Cells.UseStandardWidth = True
        End With
End Sub

検索実行VBAコード作成のまとめ

backnoken2008kai

検索のキーワードの種類として送品年月日”・”雑誌名”・”雑誌コード”としました。

そのほかに加えたいものがあれば、追加のカスタムをしていただければと思います。

この様に、検索のためのVBAコードとしては、Findメソッドが使い易いと思います。

次回第3回目は「検索コントロールパネル」をユーザーフォームで作成します。

改訂新版 てっとり早く確実にマスターできるExcel VBAの教科書
定番参考書の改定新版が、動画付きになりもっと分かり易くなった
vbastudy022a
vbastudy023a

電子書籍版「改訂新版 てっとり早く確実にマスターできるExcel VBAの教科書」をamazonで見てみる

(著者)大村あつし
(出版社)技術評論社
(税込価格)2,508円(本体2,280円+税)

30冊を超えるExcelのマクロやVBAの解説書を執筆してきた著者による考え抜かれた本書の内容と構成。
独創的な解説手法で必ずExcel VBAが理解できます!
初級からの参考書ですが、より実践的切り口での解説をしています。
QRコードから操作の流れを動画(無音です)で確認することもできるようになりました。
文章解説と動画との関係性は、主は文章での解説、サポートが動画になります。

エクセルVBAを独習するのに参考書は欠かせません。 参考書選びは自分に合った「相棒」にできるものを選んでいきたいです。

vbastudyeyecatch2 エクセルVBAの独習でおすすめ参考書を7冊選ぶ。良書との出会いは大切です

今回の記事はここまでです。   最後までご覧いただき有難うございました。

エクセルVBA最速理解で必要な知識を集めよう!

エクセルVBA業務ツールで日常の業務改善を行いましょう。

VBAコードの記述記事においては、その記述には細心の注意をしたつもりですが、掲載のVBAコードは動作を保証するものではりません。 あくまでVBAの情報の一例として掲載しています。 掲載のVBAコードのご使用は、自己責任でご判断ください。 万一データ破損等の損害が発生しても当方では責任は負いません。

アンケートでポイ活しよう!!

アンケートに答えれば答えるほど ”使える” ポイントがたまります。

NTTコム サーチ

af_banner01

Dstyle web

dstyleweb_logo
dstyle_320x50-min