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

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

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

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

マクロ

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

Q&A

3回答

1229閲覧

VBA:複数のシートを参照し、テキストに変換したい

退会済みユーザー

退会済みユーザー

総合スコア0

VBA

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

マクロ

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

0グッド

0クリップ

投稿2021/10/13 08:11

編集2021/10/14 01:37

前提・実現したいこと

sheet1の設問・回答番号を複数のシートを参照し、一致した場合にテキストへ変換したいです。

自身で対応できた範囲はコードへ記述しました
sheet1のA列とsheet2のA列が一致した場合、sheet2のB列に置換するという初歩的な所までです。

こちらを応用し対応できるかご教示いただけないでしょうか。

■sheet1の回答番号をテキストへ変換したい(既にテキストのセルはそのまま)
背景が青を実行後、緑にしたい
イメージ説明
■sheet1の2行目以下の数字はanswertitleのD列を置換したい
条件がsheet1 1行目のQ1...がanswertitle A列と一致している、かつ2行目以下の数字がC列と一致している
ただし、Q4のように_1・_2...となってる複数回答の場合は1のみしか存在しないためA列が一致してればOK
イメージ説明
■sheet1の1行目 Q1...はtitle A列が一致した場合、B列を置換したい
ただし、Q4のように_1・_2となってる複数回答の場合は_1のみ変換。_2以降は空白
イメージ説明

※複数回答時の設問・回答内容が変だと思いますが、ランダムに設定したため気になさらないようお願いいたします。

■追加のイメージ
イメージ説明

イメージ説明

該当のソースコード

VBA

1Sub テキストに置換() 2 3 Dim st1 As Worksheet 4 Dim st2 As Worksheet 5 Dim result As Range 6 Dim r As Long 7 8 Set st1 = Worksheets("Sheet1") 9 Set st2 = Worksheets("Sheet2") 10 11 r = 2 12 Do While st1.Cells(r, 1).Value <> "" 13 Set result = st2.Range("A:A").Find(st1.Cells(r, 1).Value) 14 If Not result Is Nothing Then 15 st1.Cells(r, 1).Value = st2.Cells(result.Row, 2).Value 16 End If 17 r = r + 1 18 DoEvents 19 Loop 20 21End Sub

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

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

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

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

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

hatena19

2021/10/13 08:49 編集

コードには Worksheets("Sheet2") とありますが、画像には Sheet2 はないようですが。 画像の方を信じていいのでしょうか。 タイトルは titleのB列を縦横変換して貼り付ければよさそうですが、 実際のものは、並び順が一致していない場合もあるのでしょうか。
退会済みユーザー

退会済みユーザー

2021/10/13 09:56 編集

ご確認ありがとうございます。 コードには Worksheets("Sheet2") とありますが、画像には Sheet2 はないようですが。 画像の方を信じていいのでしょうか。 >はい、画像が最新となります。  sheet2を記述しているのは、自身で対応しようと試みましたが  sheet1のA列とsheet2のA列が一致した場合、sheet2のB列をsheet1のA列に置換する  という部分までしか対応できず、そのコードを記述させていただきました。 タイトルは titleのB列を縦横変換して貼り付ければよさそうですが、 実際のものは、並び順が一致していない場合もあるのでしょうか。 >並び順は必ず上からQ1~順番通りになっております。  そのため並び順は一致しております。
guest

回答3

0

表頭に1行加えて、配列数式を使う方法でもいいのではと思います。
セルに次の式を入力して
=IF((Sheet2!A2:A17=Sheet1!A1)(Sheet2!B2:B17=Sheet1!A2)(Sheet2!C2:C17=Sheet1!A3),Sheet2!D2:D17)
Shit+Ctrl+Enterキーを押します。
![ここにイメージ説明

上記では、できないというか誤りですので下記のように修正します。
数式>名前の管理>新規作成
余裕を持って
参照範囲 Sheet2!$A$1:$A$1000 名前 label
参照範囲 Sheet2!$B$1:$B$1000 名前 id
参照範囲 Sheet2!$C$1:$C$1000 名前 answerKey
参照範囲 Sheet2!$D$1:$D$1000 名前 text
名前を作成

=IF(ISERROR(MATCH(A3,IF((label= A$2)*(id=A$1),answerKey),0)),"",INDEX(text,MATCH(A3,IF((label= A$2)*(id=A$1),answerKey),0),1))

を変換範囲の左上のセルに配列数式を入力して、このセルを変換範囲で数式コピー、
B列のような例外は、セルB10に式=B3、B11に式=B4以下略とする。
と変更します。

投稿2021/10/13 21:37

編集2021/10/14 11:01
ryusora

総合スコア26

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

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

退会済みユーザー

退会済みユーザー

2021/10/14 02:37

ご回答ありがとうございます。 こちら参考にさせていただきます。
guest

0

いろいろな方法があると思いますが、どちらにしてもかなり難易度は高そうです。

Dictionary を使った方法で書いてみました。

vba

1Sub テキストに置換() 2 3 Dim st1 As Worksheet 4 Dim stTitle As Worksheet 5 Dim stAnswer As Worksheet 6 Dim result As Range, result1 As Range 7 Dim r As Long, c As Long 8 9 Set st1 = Worksheets("Sheet1") 10 Set stTitle = Worksheets("title") 11 Set stAnswer = Worksheets("answer") 12 13 Dim dic As Object 14 Set dic = CreateObject("Scripting.Dictionary") 15 r = 2 16 With stAnswer 17 Do While stAnswer.Cells(r, 1).Value <> "" 18 If .Cells(r, 3).Value <> "" Then 19 dic(.Cells(r, 2).Value & ":" & .Cells(r, 3).Value) = .Cells(r, 4).Value 20 End If 21 r = r + 1 22 Loop 23 End With 24 25 26 With st1 27 c = 1 28 Do While .Cells(1, c).Value <> "" 29 r = 2 30 Do While .Cells(r, 1).Value <> "" 31 Dim a 32 a = Split(.Cells(1, c).Value, "_") 33 If UBound(a) = 0 Then 34 If dic.Exists(.Cells(1, c).Value & ":" & .Cells(r, c).Value) Then 35 .Cells(r, c).Value = dic(a(0) & ":" & .Cells(r, c).Value) 36 End If 37 ElseIf UBound(a) = 1 Then 38 If dic.Exists(a(0) & ":" & a(1)) Then 39 If .Cells(r, c).Value = 1 Then 40 .Cells(r, c).Value = dic(a(0) & ":" & a(1)) 41 Else 42 .Cells(r, c).Value = "" 43 End If 44 End If 45 End If 46 r = r + 1 47 Loop 48 c = c + 1 49 Loop 50 51 .Rows(1).Clear 52 stTitle.Range(stTitle.Cells(2, 2), stTitle.Cells(2, 2).End(xlDown)).Copy 53 .Cells(1, 1).PasteSpecial Paste:=xlPasteValues, Transpose:=True 54 Application.CutCopyMode = False 55 56 End With 57End Sub

投稿2021/10/13 11:30

hatena19

総合スコア34075

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

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

退会済みユーザー

退会済みユーザー

2021/10/14 01:39 編集

ご回答ありがとうございます。 いただいたコードで対応できました。 度重なる質問に応えていただき感謝いたします。 大変恐縮ですが、下記の場合も対応できるように改良するのは難しいでしょうか。 複数選択式の場合、最大で10まで選択肢がある想定。 かつ組み合わせが自由なため、answerはアンケートの設問順・パターンによっては当初添付した画像以外も存在してしまう。 (titleは固定です。) 画像が載せれなかったため■追加のイメージに追加いたしました。 answerが順不同でも対応できるコードを、もしご教示いただけるようでしたらお願いできたら幸いです。 アンケートの主なパターンとして下記3つとなります。 ・選択式(単一選択肢) ・テキスト入力(自由記述) ・選択式(複数選択肢) お手数をおかけしますが、ご確認お願いいたします。
guest

0

とりあえず雰囲気だけ。

VBA

1Option Explicit 2 3Sub sample() 4 5 Dim titleDic 'As Scripting.Dictionary 6 Dim ansDic 'As Scripting.Dictionary 7 Dim c As Range, k As String 8 9 'titleを辞書に格納 10 Set titleDic = CreateObject("Scripting.Dictionary") 11 With Sheets("title") 12 For Each c In .UsedRange.Resize(, 1) 13 k = c.Value 14 titleDic (k) = c.Offset(, 1).Value 15 Next 16 End With 17 18 'answerを辞書に格納 19 Set ansDic = CreateObject("Scripting.Dictionary") 20 With Sheets("answer") 21 For Each c In .UsedRange.Resize(, 1) 22 If InStr(c.Value, "_") = 0 Then 23 k = c.Value & vbTab & c.Offset(, 2).Value 24 Else 25 k = c.Value 26 End If 27 ansDic(k) = c.Offset(, 3).Value 28 Next 29 End With 30 31 With Sheets("Sheet1") 32 '各セルの値をanswer辞書で変換 33 For Each c In .UsedRange.Resize(.UsedRange.Rows.Count - 1).Offset(1) 34 k = .UsedRange(1, c.Column) 35 If InStr(k, "_") = 0 Then 36 k = k & vbTab & c.Value 37 End If 38 If ansDic.Exists(k) Then 39 c.Value = ansDic(k) 40 c.Interior.ThemeColor = xlThemeColorAccent6 41 End If 42 Next 43 44 'titleの行をtitle辞書で変換 45 For Each c In .UsedRange.Resize(1) 46 If titleDic.Exists(c.Value) Then 47 c.Value = titleDic(c.Value) 48 ElseIf titleDic.Exists(Split(c.Value, "_")(0)) Then 49 c.Value = titleDic(Split(c.Value, "_")(0)) 50 Else 51 c.Value = "" 52 End If 53 c.Interior.ThemeColor = xlThemeColorAccent6 54 Next 55 End With 56End Sub 57

投稿2021/10/13 11:08

編集2021/10/13 22:23
jinoji

総合スコア4592

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

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

退会済みユーザー

退会済みユーザー

2021/10/14 02:46

ご回答ありがとうございます。 '各セルの値をanswer辞書で変換 For Each c In .UsedRange.Resize(.UsedRange.Rows.Count - 1).Offset(1) ⇒ k = .UsedRange(1, c.Column) 上記部分で 引数の数が一致していません。とエラーになってしまうのですが原因お分かりになりますでしょうか。 お手数をおかけしますが、ご確認お願いいたします。
jinoji

2021/10/14 03:54

失礼しました。 k = c.Offset(c.Row - 1).Value ではいかがでしょうか。
退会済みユーザー

退会済みユーザー

2021/10/14 04:39

ご確認・返信ありがとうございます。 titleは問題なく置換ができました。 ですが、answerが置換されずそのままとなっています。 何度も恐縮ですが、原因お分かりになりますでしょうか。
jinoji

2021/10/14 05:20

置換前のtitleと値の組み合わせで辞書を見に行くので、 titleが置換されたあとだとanswerが置換できないことになります。 そういうことではないとしたら、ちょっとわかりません。
退会済みユーザー

退会済みユーザー

2021/10/14 06:57

詳細ありがとうございます。 いただいたコードを自身で確認してみます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問