hayatedonda
@hayatedonda

Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

VBAでランダム出力マクロをつくりたいです!

解決したいこと

VBAで書きたいのですが、
C列の中からランダムにセルのテキストを取得し、D列からG列に出力します。
出力先の各列に対して、被らないように確認し、被らない場合にセルに値を設定したいです。
以下のコードだと文字が出力されない為、解決方法を教えて下さい。

    C列     D列      E列        G列
リンクのタグ		リンクのタグ		
文章内の略称や頭字語のテキストのタグ				文章内の略称や頭字語のテキストのタグ
コンテンツの作者の連絡先のタグ	コンテンツの作者の連絡先のタグ			
mapのクリックする場所を決めるタグ		mapのクリックする場所を決めるタグ		
単独で扱える記事のようなセクションのタグ	単独で扱える記事のようなセクションのタグ			
本筋から逸れる解説などのセクションのタグ		本筋から逸れる解説などのセクションのタグ		
ページ内に音声ファイルを埋め込むタグ	ページ内に音声ファイルを埋め込むタグ			
文章内の慣習上太字にするテキストのタグ				文章内の慣習上太字にするテキストのタグ
ページ内の相対URLの基準になるURLのタグ		ページ内の相対URLの基準になるURLのタグ		
文章内の書く方向を独立させるテキストのタグ				文章内の書く方向を独立させるテキストのタグ
文章内の書く方向を決めるテキストのタグ				文章内の書く方向を決めるテキストのタグ
引用するコンテンツのタグ		引用するコンテンツのタグ		
ブラウザに表示する内容全体のタグ	ブラウザに表示する内容全体のタグ			
文章内の改行のタグ			文章内の改行のタグ	
フォーム内のボタンのタグ		フォーム内のボタンのタグ		
ページ内にcanvasを埋め込むタグ		ページ内にcanvasを埋め込むタグ		
テーブルに付けるキャプションのタグ				テーブルに付けるキャプションのタグ
文章内の作品のタイトルのタグ		文章内の作品のタイトルのタグ		
文章内のプログラムなどのコードのタグ				文章内のプログラムなどのコードのタグ
テーブル内の縦列をまとめるタグ			テーブル内の縦列をまとめるタグ	
colタグをまとめるタグ	colタグをまとめるタグ			
右クリックメニューやキーボード操作の内容のタグ	右クリックメニューやキーボード操作の内容のタグ			
フォーム内の入力項目に選択肢をつけるタグ		フォーム内の入力項目に選択肢をつけるタグ		
項目に関する記述リストの記述のタグ				項目に関する記述リストの記述のタグ
後から削除するコンテンツのタグ		後から削除するコンテンツのタグ		
クリックすると見られる詳細情報のタグ		クリックすると見られる詳細情報のタグ		
文章内の定義する用語のテキストのタグ		文章内の定義する用語のテキストのタグ		
特定の意味を持たないブロックのタグ			特定の意味を持たないブロックのタグ	
項目に関する記述リストのタグ				項目に関する記述リストのタグ
項目に関する記述リストの項目のタグ	項目に関する記述リストの項目のタグ			
文章内の特に強調するテキストのタグ			文章内の特に強調するテキストのタグ	
ページ内に主にFlash等を埋め込むタグ		ページ内に主にFlash等を埋め込むタグ		
フォーム内の内容をまとめるタグ			フォーム内の内容をまとめるタグ	
図表や画像につける説明のタグ		図表や画像につける説明のタグ		
図表や画像とその説明をまとめるタグ	図表や画像とその説明をまとめるタグ			
コンテンツのフッター情報をまとめるタグ				コンテンツのフッター情報をまとめるタグ
フォームのタグ				フォームのタグ
見出しのタグ1		見出しのタグ1		
見出しのタグ2				見出しのタグ2
見出しのタグ3				見出しのタグ3
見出しのタグ4	見出しのタグ4			
見出しのタグ5				見出しのタグ5
見出しのタグ6		見出しのタグ6		
ページ自体のメタ情報をまとめるタグ			ページ自体のメタ情報をまとめるタグ	
コンテンツのヘッダー情報をまとめるタグ				コンテンツのヘッダー情報をまとめるタグ
二つ以上の見出しをまとめるタグ				二つ以上の見出しをまとめるタグ
段落と段落の区切りのタグ	段落と段落の区切りのタグ			
HTML自体のタグ		HTML自体のタグ		
文章内の慣習上斜体にするテキストのタグ			文章内の慣習上斜体にするテキストのタグ	
ページ内にフレームを埋め込むタグ			ページ内にフレームを埋め込むタグ	
写真や画像のタグ		写真や画像のタグ		
フォーム内の入力項目のタグ			フォーム内の入力項目のタグ	
後から追記するコンテンツのタグ			後から追記するコンテンツのタグ	
文章内の入力テキストかキーボードのキーのタグ				文章内の入力テキストかキーボードのキーのタグ
フォーム内で暗号になるキーを作るタグ	フォーム内で暗号になるキーを作るタグ			
フォーム内の項目にラベルを付けるタグ	フォーム内の項目にラベルを付けるタグ			
fieldsetタグにつけるタイトルのタグ	fieldsetタグにつけるタイトルのタグ			
リストの内容のタグ			リストの内容のタグ	
外部ファイルとのリンクのタグ				外部ファイルとのリンクのタグ
クリックできるイメージマップのタグ			クリックできるイメージマップのタグ	
文章内の目立たせたテキストのタグ		文章内の目立たせたテキストのタグ		
ツールバーや右クリックメニューを埋め込むタグ	ツールバーや右クリックメニューを埋め込むタグ			
ページ自体のメタ情報のタグ	ページ自体のメタ情報のタグ			
予め数値の決まったゲージのタグ			予め数値の決まったゲージのタグ	
リンクをまとめるセクションのタグ	リンクをまとめるセクションのタグ			
主にJavaScriptの代わりに表示するコンテンツのタグ			主にJavaScriptの代わりに表示するコンテンツのタグ	
ページ内に画像や音声、動画を埋め込むタグ				ページ内に画像や音声、動画を埋め込むタグ
順番の決まったリストのタグ				順番の決まったリストのタグ
フォーム内の複数のoptionタグをまとめるタグ			フォーム内の複数のoptionタグをまとめるタグ	
フォーム内のメニューの選択肢のタグ				フォーム内のメニューの選択肢のタグ
フォーム内の計算結果の出力のタグ		フォーム内の計算結果の出力のタグ		
段落のタグ		段落のタグ		
objectタグのコンテンツのパラメータのタグ				objectタグのコンテンツのパラメータのタグ
書いたままのテキストを表示するタグ				書いたままのテキストを表示するタグ
処理の進捗状況などのゲージのタグ	処理の進捗状況などのゲージのタグ			
文章内の引用部分のテキストのタグ			文章内の引用部分のテキストのタグ	
ルビが表示されない場合のカッコのタグ		ルビが表示されない場合のカッコのタグ		
ルビとして付くテキストのタグ				ルビとして付くテキストのタグ
文章内のルビを付けるテキストのタグ		文章内のルビを付けるテキストのタグ		
文章内の打ち消し線のついたテキストのタグ				文章内の打ち消し線のついたテキストのタグ
文章内のプログラムで出力するテキストのタグ		文章内のプログラムで出力するテキストのタグ		
主にJavaScriptをページに埋め込むタグ				主にJavaScriptをページに埋め込むタグ
見出しと内容をまとめるセクションのタグ	見出しと内容をまとめるセクションのタグ			
フォーム内のメニューのタグ				フォーム内のメニューのタグ
文章内の補足や細目のテキストのタグ	文章内の補足や細目のテキストのタグ			
ページ内に埋め込む動画や音声を指定するタグ				ページ内に埋め込む動画や音声を指定するタグ
文章内の特定の意味を持たないテキストのタグ			文章内の特定の意味を持たないテキストのタグ	
文章内の重要性の高いテキストのタグ		文章内の重要性の高いテキストのタグ		
主にCSSをページ自体に書き込むタグ			主にCSSをページ自体に書き込むタグ	
文章内の下に付くテキストのタグ			文章内の下に付くテキストのタグ	
detailタグにつけるラベルのタグ			detailタグにつけるラベルのタグ	
文章内の上に付くテキストのタグ				文章内の上に付くテキストのタグ
テーブルのタグ	テーブルのタグ			
テーブル内のボディ部分のデータをまとめるタグ		テーブル内のボディ部分のデータをまとめるタグ		
テーブル内の行の内容のタグ			テーブル内の行の内容のタグ	
フォーム内の文章の入力項目のタグ			フォーム内の文章の入力項目のタグ	
テーブル内のフッター部分の行のタグ				テーブル内のフッター部分の行のタグ
テーブル内の行の見出しのタグ		テーブル内の行の見出しのタグ		
テーブル内のヘッダー部分の行のタグ		テーブル内のヘッダー部分の行のタグ		
文章内の日時のタグ				文章内の日時のタグ
ページ自体の題名のタグ				ページ自体の題名のタグ
テーブル内の行のタグ			テーブル内の行のタグ	
動画や音声と同期するテキストトラックのタグ			動画や音声と同期するテキストトラックのタグ	
文章内の慣習上下線を引くテキストのタグ	文章内の慣習上下線を引くテキストのタグ			
順番の決まってないリストのタグ	順番の決まってないリストのタグ			
文章内の変数のテキストのタグ	文章内の変数のテキストのタグ			
ページ内に動画ファイルを埋め込むタグ			ページ内に動画ファイルを埋め込むタグ	
文章内の改行可能な位置のタグ			文章内の改行可能な位置のタグ	

Sub ランダム出力マクロ()
    Dim ws As Worksheet
    Dim lastRow As Long
    Dim cColumn As Range, outputRange As Range
    Dim cell As Range
    Dim outputCell As Range
    
    ' 対象のワークシートを指定
    Set ws = ThisWorkbook.Sheets("Sheet4") ' Sheet4を対象
    
    ' 最終行を取得
    lastRow = ws.Cells(ws.Rows.Count, "C").End(xlUp).Row
    
    ' 対象の列を指定
    Set cColumn = ws.Range("C2:C" & lastRow) ' C列のデータが入っている範囲を指定
    Set outputRange = ws.Range("D2:G" & lastRow) ' 出力先の列を指定
    
    ' ランダムなセルからテキストを取得
    Set cell = cColumn.Cells(Int((lastRow - 1) * Rnd) + 2)
    
    ' すでにデータが入っていない場合、出力先の各列に被らないようにセルの値を設定
    If WorksheetFunction.CountIf(outputRange, cell.Value) = 0 Then
        For Each outputCell In outputRange.Rows(cell.Row - 1).Cells
            If IsEmpty(outputCell.Value) Then
                outputCell.Value = cell.Value
                Exit For
            End If
        Next outputCell
    End If
End Sub

0

3Answer

↓こういうことでしょうか?

Sub ランダム出力マクロ()
    Dim ws As Worksheet
    Dim lastRow As Long
    Dim cColumn As Range, outputRange As Range
    Dim cell As Range
    Dim outputCell As Range
    Dim row As Long, col As Long
    Dim r As Variant
    Dim ok As Boolean
    
    Randomize
    
    ' 対象のワークシートを指定
    Set ws = ThisWorkbook.Sheets("Sheet4") ' Sheet4を対象
    
    ' 最終行を取得
    lastRow = ws.Cells(ws.Rows.Count, "C").End(xlUp).row
    
    ' 対象の列を指定
    Set cColumn = ws.Range("C2:C" & lastRow) ' C列のデータが入っている範囲を指定
    
    For row = 2 To lastRow
        For col = 5 To 7  'E〜G
            ok = False
            Do
                ' ランダムなセルからテキストを取得
                Set cell = cColumn.Cells(Int((lastRow - 1) * Rnd) + 2)
                Set outputRange = ws.Range(ws.Cells(row, 3), ws.Cells(row, 7))
                
                ' すでにデータが入っていない場合、出力先の各列に被らないようにセルの値を設定
                r = WorksheetFunction.CountIf(outputRange, cell.Value)
                If IsEmpty(r) Or (r = 0) Then
                    ws.Cells(row, col) = cell.Value
                    ok = True
                End If
            Loop While Not ok
        Next
    Next
    
End Sub
2Like

Comments

  1. @hayatedonda

    Questioner

    そのコードで実行したら、E列F列G列は変わりましたが、D列が変わっていませんでした。
    また、元々セルに入っていたデータも書き換わってしまいました。

  2. でしたら、↓こちらです。

    Option Explicit
    
    Sub ランダム出力マクロ()
        Dim ws As Worksheet
        Dim lastRow As Long
        Dim cColumn As Range, outputRange As Range
        Dim cell As Range
        Dim outputCell As Range
        Dim row As Long, col As Long
        Dim r As Variant
        
        Randomize
        
        ' 対象のワークシートを指定
        Set ws = ThisWorkbook.Sheets("Sheet4") ' Sheet4を対象
        
        ' 最終行を取得
        lastRow = ws.Cells(ws.Rows.Count, "C").End(xlUp).row
        
        ' 対象の列を指定
        Set cColumn = ws.Range("C2:C" & lastRow) ' C列のデータが入っている範囲を指定
        
        For row = 2 To lastRow
            For col = 4 To 7  'D〜G
                Do While IsEmpty(ws.Cells(row, col))
                    ' ランダムなセルからテキストを取得
                    Set cell = cColumn.Cells(Int((lastRow - 1) * Rnd) + 2)
                    Set outputRange = ws.Range(ws.Cells(row, 4), ws.Cells(row, 7))
      
                    ' すでにデータが入っていない場合、出力先の各列に被らないようにセルの値を設定
                    r = WorksheetFunction.CountIf(outputRange, cell.Value)
                    If IsEmpty(r) Or (r = 0) Then
                        ws.Cells(row, col) = cell.Value
                    End If
                Loop
            Next
        Next
    End Sub
    
  3. @hayatedonda

    Questioner

    ありがとうございます!
    出来ました!一個一個確認して勉強していきます!

  4. 解決したのでしたら、質問をクローズしましょう。

こちらのマクロが意図したように動作しないのは、D列に既に値があるからではないでしょうか。

1Like

Comments

  1. @hayatedonda

    Questioner

    D列からG列には元々1つデータが入っており、その他の行をC列の中から被らないセルの文字を出力したいです。その際に行で見た時文字列が被らないようにしたいです。

文字が追加されない理由

文字が何も追加されない理由だけで言えば、
C列に格納されている、評価される対象の文字列↓

 ' ランダムなセルからテキストを取得
    Set cell = cColumn.Cells(Int((lastRow - 1) * Rnd) + 2)

これと同等の値が、同じ行のD列~G列に必ず入っているのであれば、
WorksheetFunction.CountIf(outputRange,cell.Value) は必ず1になります。
これは、outputRangeが各列ではなく、D列~G列を含んだ範囲だからです。
なので、worksheetFunction.CountIF句があるIf文の中に入れないので、
文字が追加されていない、という事になります。

やりたい事が不明瞭

現在の文面とコードだと、投稿者様のやりたい事が見えて来ないので、
解決方法を明示出来ません。
ただ、一旦ショートステップで改めて構築し直してみたら如何でしょうか。

まずデータの行数を5行など大幅に減らした上で、かつ対象列はD列のみにして、
それで想定通りの動きになったとしたら、対象列を増やすと良いと思います。

別件

Rnd関数はシード値という値が内部的に存在し、
これの影響でExcelを起動した時にシード値が毎回同じ値になってしまう事で、
乱数が乱数ではなくなるので、直前にrandomize句を入れましょう。

    ' ランダムなセルからテキストを取得
    Randomize
    Set cell = cColumn.Cells(Int((lastRow - 1) * Rnd) + 2)
1Like

Comments

  1. @hayatedonda

    Questioner

    ショートステップで改めて構築し直してみます。

Your answer might help someone💌