Excel VBA

【Excel VBA】【マクロ】【Tips】指定した列数に応じて出力列を変更する

こんにちは!Lenocoです。本日も見てくださりありがとうございます。

今回は出力列制御についてのTips回です!!!

指定した列数に応じて出力列を変更するマクロ

以前のブログ、「氏名のダミーデータを自動作成するマクロ」で、名前をランダム生成し性別とともに出力するマクロを作り、
「指定した年齢の範囲でランダムで生年月日を出力するマクロ」で、最少年齢と最大年齢を入力し、その範囲内で生年月日を出力するマクロを作成しました。

今回は、上記2つを組み合わせたマクロに、ちょこっと機能を追加・修正を加えたので
その内容をご説明したいと思います!!!

コード

Sub CreateDummyData()

    Dim data1() As Variant          '苗字配列
    Dim data2() As Variant          '名前配列
    Dim outputTitleAns As Long      'タイトル出力判定用
    Dim outputNum As Long           '出力件数保存用
    Dim outputSexAns As Long        '性別出力判定用
    Dim outputBirthdayAns As Long   '生年月日出力判定用
    Dim outputMinAge As Long        '最小年齢
    Dim outputMaxAge As Long        '最高年齢
    Dim tgtDate As Date             '基準日保存用
    Dim rand As Long                '乱数保存用
    Dim i As Long                   'ループ用変数
    Dim outputRow As Long           '出力行
    Dim col As Long                 '列番号保存用
    Dim name As String              '氏名保存用
    Dim adjust As Long              '列調整用

    '初期値設定
    outputNum = 0
    outputRow = Selection.Row
    col = Selection.Column
    adjust = 1

    data1 = Array("山崎", "森", "池田", "橋本", "阿部", "石川", "山下", "中島", "石井", "小川", _
                "前田", "岡田", "長谷川", "藤田", "後藤", "近藤", "村上", "遠藤", "青木", "坂本", _
                "斉藤", "福田", "太田", "西村", "藤井", "金子", "岡本", "藤原", "三浦", "中野", _
                "中川", "原田", "松田", "竹内", "小野", "田村", "中山", "和田", "石田", "森田", _
                "上田", "原", "内田", "柴田", "酒井", "宮崎", "横山", "高木", "安藤", "宮本", _
                "大野", "小島", "谷口", "工藤", "今井", "高田", "増田", "丸山", "杉山", "村田", _
                "大塚", "新井", "小山", "平野", "藤本", "河野", "上野", "野口", "武田", "松井", _
                "千葉", "菅原", "岩崎", "木下", "久保", "佐野", "野村", "松尾", "菊地", "市川", _
                "杉本", "古川", "大西", "島田", "水野", "桜井", "高野", "渡部", "吉川", "山内", _
                "西田", "飯田", "菊池", "西川", "小松", "北村", "安田", "五十嵐", "川口", "平田")

    data2 = Array("愛", "彩", "美穂", "愛美", "千尋", "舞", "美咲", "麻衣", "瞳", "沙織", _
                "恵", "彩香", "茜", "美里", "早紀", "麻美", "未来", "明日香", "美紀", "香織", _
                "あゆみ", "詩織", "成美", "綾香", "由佳", "智美", "彩乃", "友美", "美香", "仁美", _
                "桃子", "梓", "佳奈", "栞", "綾", "恵美", "萌", "めぐみ", "唯", "里奈", _
                "美樹", "菜摘", "理沙", "綾乃", "優", "翔子", "理恵", "美幸", "智子", "春菜", _
                "翔太", "拓也", "健太", "翔", "大樹", "駿", "大輔", "翔平", "亮", "達也", _
                "直人", "直樹", "大地", "雄太", "亮太", "翼", "健人", "諒", "和也", "裕太", _
                "優", "卓也", "大介", "健太郎", "恭平", "貴大", "康平", "大輝", "涼", "拓馬", _
                "大貴", "裕也", "光", "雄大", "直也", "誠", "健", "一樹", "祐太", "洋平", _
                "航", "和樹", "遼", "匠", "祐樹", "裕介", "一馬", "優太", "裕貴", "駿介")

    '何件出力するか入力
    outputNum = Application.InputBox("何件出力しますか?", "出力件数確認", "", Type:=1)
    'タイトル行を出力するか確認
    outputTitleAns = MsgBox("タイトル行を出力しますか?", vbYesNo + vbInformation)
    '性別も出力するか確認
    outputSexAns = MsgBox("性別も出力しますか?", vbYesNo + vbInformation)
    '生年月日を出力するか確認
    outputBirthdayAns = MsgBox("生年月日も出力しますか?", vbYesNo + vbInformation)
    If outputBirthdayAns = vbYes Then
        outputMinAge = Application.InputBox("出力したい最小年齢を入力してください。", "最小年齢確認", "", Type:=1)
        outputMaxAge = Application.InputBox("出力したい最高年齢を入力してください。", "最高年齢確認", "", Type:=1)
    End If

    'タイトルの出力
    If outputTitleAns = vbYes Then
        ActiveSheet.Cells(outputRow, col) = "氏名"
        If outputSexAns = vbYes Then
            ActiveSheet.Cells(outputRow, col).Offset(, adjust) = "性別"
            adjust = adjust + 1
        End If
        If outputBirthdayAns = vbYes Then
            ActiveSheet.Cells(outputRow, col).Offset(, adjust) = "生年月日"
        End If
        outputRow = outputRow + 1
    End If

    For i = 1 To outputNum
        adjust = 1

        '苗字
        rand = Int(100 * Rnd)
        name = data1(rand)

        '名前
        rand = Int(100 * Rnd)
        name = name & " " & data2(rand)

        ActiveSheet.Cells(outputRow, col) = name
        If outputSexAns = vbYes Then
            If rand <= 49 Then
                ActiveSheet.Cells(outputRow, col).Offset(, adjust) = "女性"
            Else
                ActiveSheet.Cells(outputRow, col).Offset(, adjust) = "男性"
            End If
            adjust = adjust + 1
        End If
        If outputBirthdayAns = vbYes Then
            rand = Int((outputMaxAge - outputMinAge + 1) * Rnd + outputMinAge)
            tgtDate = DateAdd("yyyy", -rand, Date)
            With ActiveSheet.Cells(outputRow, col).Offset(, adjust)
                .Value = Int((tgtDate - (tgtDate - 364) + 1) * Rnd + (tgtDate - 364))
                .NumberFormatLocal = "yyyy/m/d"
            End With
        End If
        outputRow = outputRow + 1
    Next i

    MsgBox outputNum & "件出力完了!"

End Sub

コードの説明

追加した部分・修正した部分のみ解説しますね。
そもそもまず、どんな追加・変更をしたのかについてご説明します。

追加

1.タイトル行を出力するかどうかを選択できるようにしました。
タイトル行出力判定用に「outputTitleAns」という変数をLong型で作成します。
2.出力件数をダイアログボックスで確認したあと、タイトルを出力するかどうかをダイアログボックスで確認します。
性別や生年月日同様Msgbox関数を使用します。
3.For文でダミーデータを出力する直前で、タイトル行を出力する処理をいれます。
タイトルはそれぞれ「氏名」「性別」「生年月日」としています。
「氏名」は固定で出力します。出力先はマクロ実行時に選択されていたセルです。
性別を出力と選択されていた場合、「性別」を右のセルに出力します。
生年月日を出力と選択されていた場合、「生年月日」をさらに右のセルに出力します。
※今回「adjust」という変数を使用し、出力先列を調整しています。次の「修正」でご説明します。
If文の最後で出力行「outputRow」に+1しています。これをしておかないと、タイトルがデータで上書きされてしまうので注意です!

修正

続いて修正の部分についてです。
「氏名のダミーデータを自動作成するマクロ」で、性別を出力すると選択した場合、
必ず氏名の右隣りの列が性別を出力する列となるため、Offset関数を使用し、基準となるセルから列番号+1したセルを参照するようにしていました。

ActiveSheet.Cells(outputRow, col).Offset(, 1) = "女性"

「指定した年齢の範囲でランダムで生年月日を出力するマクロ」を組み合わせた場合、同じ要領で列を指定すると、[基準セル].Offset(, 2)という指定になると思います。
ですがこのように固定数で指定してしまうと、仮に「性別出力なし」「生年月日出力あり」と選択した場合に、
「氏名列、空白列、生年月日列」という謎の空白列ができてしまいます。

出力例(出力数:5、タイトル:あり、性別:なし、生年月日:あり 20-59歳で指定した場合)

これはとっても微妙ですよね。
出力すると選択した項目を左詰めにするのが本来の正しい動きになると思います。
そこで今回の修正を行いました。
一つずつ見ていきましょう。
1.まず数値型の「adjust」という変数を作成します。
Offset関数の列数に使用する変数となります。
初期値として1を設定しておきます。

2.タイトルを出力する処理と、データを出力する処理で、「adjust」の使い方は一緒なので、タイトルの部分で説明します。
●「性別・生年月日どちらも出力あり」の場合
「性別を出力する」と指定された場合、
初期値で「adjust=1」と設定しているので、「氏名」の右隣のセルに「性別」と出力されます。
そしてIf文の最後で「adjust」を+1しています。今「adjust」には「2」が入っています。
こうすることで、次のタイトルをさらに右隣りのセルに出力できます。
続いて、「生年月日を出力する」と指定された場合、
現在「adjust」は「2」となっているので、基準セルから2つ右のセルに「生年月日」と出力されます。
「性別出力なし・生年月日は出力あり」の場合
「性別を出力しない」かつ「生年月日を出力する」とした場合はどうなるでしょうか。
性別出力なしのため、性別を出力するIf文には入りません。
そのため、「adjust」は初期値の「1」のままとなります。
続いて生年月日のIf文に入り、「氏名」の右隣のセルに「生年月日」と出力されます。

3.For文でダミーデータを出力する時は、For文の最初で必ず「adjust=1」とする必要があります。
こうしないと、性別を出力する処理の中の「adjust=adjust+1」で、「adjust」がどんどん加算されてしまいます。
Forの先頭で必ず出力列をリセットする必要があります。

コードの説明は以上となります。

さいごに

次回は、このダイアログボックスの部分をすべてフォームに変換していきたいと思います!!

【Excel VBA】【マクロ】【Tips】氏名のダミーデータを自動作成するマクロこんにちは!Lenocoです。本日も見てくださりありがとうございます。 今回はダミーデータ作成についてのTips回です!!! 苗字と名...
【Excel VBA】【マクロ】【Tips】指定した年齢の範囲でランダムで生年月日を出力するマクロこんにちは!Lenocoです。本日も見てくださりありがとうございます。 今回はランダムな日付データ作成についてのTips回です!!! ...
【Excel VBA】【マクロ】【Tips】ユーザーフォームの呼び出し方こんにちは!Lenocoです。本日も見てくださりありがとうございます。 今回はユーザーフォームについてのTips回です!!! 過去の...

Lenoco

COMMENT

メールアドレスが公開されることはありません。 が付いている欄は必須項目です