[[20160809085653]] 『チェックボックスで選択した項目のみセルに』(ねこ) ページの最後に飛ぶ

[ 初めての方へ | 一覧(最新更新順) | 全文検索 | 過去ログ ]

 

『チェックボックスで選択した項目のみセルに』(ねこ)

ユーザーフォームについての質問です。

今とあるユーザーフォームを作成しているのですが、一部やり方がわからず
困ってしまっています。

やりたいことは、
ユーザーフォームにチェックボックスとラベルを設置→ラベルには項目1-1〜1-5と記入し、その横にそれぞれチェックボックスを置く→ほしい項目(例:1-1・1-4・1-5にチェック)をクリックする→そうするとエクセルのsheet1のB17〜記入

説明がわかりづらく申し訳ありません。
つまり、項目1-1〜1-5は入る場合と入らない場合があるので選んだ項目をB17からつめて記入したいです。
セル指定を行うとシートに記入自体はできるのですが、選択しなかった項目分空白行ができてしまいます。
開始位置は必ずB17固定です。

よろしくお願いいたします。

< 使用 Excel:Excel2010、使用 OS: >


一部やりかたがわからずなら、わかる部分のコードを貼ってください。
(x) 2016/08/09(火) 09:51

>x様

すみません、説明不足でした。
一部やり方がわからず、というのはその他の全く別の部分のユーザーフォームはできていて
上記で質問させていただいたものは全く分かっていない状況です。
こちらができれば望んでいるユーザーフォームが完成します。

ややこしい言い方をしてしまい申し訳ありません。

よろしくお願いいたします。
(ねこ) 2016/08/09(火) 10:18


そこまで作成できた方が、チェックボックスのコーディングを判らないはずがないと思うのですが…?

 Private Sub CheckBox1_Click()
    Sheets("Sheet1").Range("B17") = CheckBox1.Value
 End Sub
(???) 2016/08/09(火) 11:00

???様、ご回答ありがとうございます。

わざわざ作成していただき申し訳ないのですが、今回聞きたいことは
普通にB17に記入であれば上記の式でできるのですが、それを選択した項目だけつめて記入という部分で困ってしまっています。

例1:チェックボックスで1-1、1-4、1-5をクリック→するとセルにはB17に「1-1」B18に「1-4」B19に「1-5」が入る
例2:チェックボックスで1-2、1-3、1-4をクリック→するとセルにはB17に「1-2」B18に「1-3」B19に「1-4」が入る

このような挙動を行いたいです。

このような場合どのような式になるのでしょうか?
よろしくお願いいたします。

(ねこ) 2016/08/09(火) 11:13


別にボタンを追加して
Private Sub CommandButton1_Click()

    Dim i As Integer
    Dim j As Integer

    For i = 1 To 5

        If Me.Controls("CheckBox" & i) Then
            Range("B17").Offset(j) = "'1-" & i
            j = j + 1
        End If

    Next

End Sub

(x) 2016/08/09(火) 11:19


チェックボックスが5つしか配置されていないとして、例えば以下の感じですかね。

 Private Sub CheckBox1_Click()
    Call sB17
 End Sub

… (1〜5まで、全て同じプロシジャをコール)

 Private Sub CheckBox5_Click()
    Call sB17
 End Sub

 Sub sB17()
    Dim cDim() As String
    Dim iC As Long
    Dim i As Long
    Dim iw As Long

    For i = 0 To Controls.Count - 1
        If 0 < InStr(Controls(i).Name, "CheckBox") Then
            iw = Mid(Controls(i).Name, 9)
            If Controls(i).Value = True Then
                ReDim Preserve cDim(iC)
                cDim(iC) = "1-" & iw
                iC = iC + 1
            End If
        End If
    Next i

    Sheets("Sheet1").Range("B17:B21").ClearContents
    For i = 0 To iC - 1
        Sheets("Sheet1").Cells(17 + i, "B").Value = cDim(i)
    Next i
 End Sub
(???) 2016/08/09(火) 12:03

 横から失礼します。

 >>チェックボックスとラベルを設置→ラベルには項目1-1〜1-5と記入し、その横にそれぞれチェックボックスを置く

 セルに書きこむべき文字列は ラベルに記載されている。いいかえるとラベルのキャプションですか?

 ・もし、そうであれば、どのチェックボックスと、どのラベルがついになっているかの紐付けが必要です。
  たとえば CHeckBox1 と Label1 とか、ckb_1 と lbl_1 とか。
 ・ふつうは、ラベルを配置せず、チェックボックスそのもののキャプションにすると思いますが?
  そうすればコントロールの数も減りますし、チェックボックスとラベルの名前の紐つけも不要ですので。

 で、セルに詰めてセットすべき、そのチェックボックスなんですが、どのチェックボックスからどのチェックボックスまでということを明確にしてください。
 CheckBox1からCheckBox5までとか、ckb_1からckb_5までとか。

 あるいは、ユーザーフォーム上にあるすべてのチェックボックスを相手にしていいなら、それはそれで可能ですが。

 なお、転記方法としては、必要なチェックボックスの数だけある複数行1列の配列を準備して、チェックされているものを
 その配列に上から順番に格納しておいて、Range("B17").Resize(Ubound(その配列,1).Value = その配列 ということも
 できますね。

(β) 2016/08/09(火) 12:21


x様・???様・β様、ご回答ありがとうございます。

x様・???様のコードを使用させていただいたところどちらもきちんと挙動してくれました。
ありがとうございます。

β様
ラベルはただどのチェックボックスを押せばどの項目がでるかというただの名前付けの意味で置いてありました。
チェックボックス自体に記入できることにさきほど気づいたのでそちらは修正いたしました。

先ほど新たなやってほしいことが増えてしまってまた悩んでおります。

チェックボックスで必要項目選択→セルに記入
この時にボタンを押すと、別シート「集計」に選んだものが黒丸で記入されるということも行いたいです。

(例)チェックボックスで「1-2・1-4」を選択した場合
A   B  C  D  E  F
記号 1-1 1-2 1-3 1-4 1-5
あ      ●     ●

また、セルB17〜に1-1などが記入されると、J17に「式」という言葉も入ってほしいのですが、こちらは関数で行うほうがいいのでしょうか?

追加で申し訳ありません。
よろしくお願いいたします。
(ねこ) 2016/08/09(火) 13:11


ここはやって欲しいことを頼む場所ではなく、自分で考えたり作ったりしていくうちに判らない事がでてきた際に尋ねる場所ですよ。自分で試しもしないで質問しないように願います。

●の件は、別シートのフォーマットが不明なので、貴方が作るしかないです。
「式」の件は、私のコーディング中で iC という変数がチェックされている数になっているので、これが0より大きかったら文字表示、というコーディングにするだけかと。
(???) 2016/08/09(火) 13:18


???様、ご回答ありがとうございます。

そうですね。すこし自分で考えてみようと思います。
申し訳ありません。

最後に一つだけ質問なのですが、今回例として「1-1」という風にあげさせていただいたのですが
この項目が普通の文字列(ひとつひとつに関連性はなし)の場合「cDim(iC) = "1-" & iw」の部分は
どのように書き換えればよろしいのでしょうか?
チェックボックスのCaptionにはそれぞれ文字列を記入してあります。

よろしくお願いいたします。
(ねこ) 2016/08/09(火) 15:23


私が Controls(i).Name と書いていた部分を、Controls(i).Caption を参照するよう変えてみてください。
(.Nameの場合、コントロール名ですが、.Captionとすれば設定した文字列が得られます)

iwは、CheckBoxの番号ですが、文字列を直接使うならば iw を使わず、Controls(i).Caption をそのまま使えば良いでしょう。
(iw という変数自体が不要になります)
(???) 2016/08/09(火) 15:52


???様、ご回答ありがとうございます。

Sub sB17()

    Dim cDim() As String
    Dim iC As Long
    Dim i As Long
    Dim iw As Long
    For i = 0 To Controls.Count - 1
        If 0 < InStr(Controls(i).Caption, "CheckBox") Then
            If Controls(i).Value = True Then
                ReDim Preserve cDim(iC)
                cDim(iC) = Controls(i).Caption
                iC = iC + 1
            End If
        End If
    Next i
    Sheets("Sheet1").Range("B17:B21").ClearContents
    For i = 0 To iC - 1
        Sheets("Sheet1").Cells(17 + i, "B").Value = cDim(i)
    Next i
 End Sub

私なりに修正したのですが、エラーはでないのですが結果が反映されませんでした。
私の考え方が悪いと思うのですが、どの部分がだめでしょうか?
シート名の部分が悪いのかと思ったのですが、シート名は現在(Sheet1)にしています。

よろしくお願いいたします。
(ねこ) 2016/08/09(火) 16:09


問題箇所は、以下。

 > If 0 < InStr(Controls(i).Caption, "CheckBox") Then

コントロール名に"CheckBox"が含まれることで、該当オブジェクトがチェックボックスであることを判定していますので、ここはCaptionに変えてはいけません。ここは元のまま、.Name で判定してください。変えるのは、cDimに代入している箇所だけです。
(???) 2016/08/09(火) 16:56


 横から失礼します。

 ユーザーフォーム上のコントロール名をデフォルトから特定のものに変更するということは
 実務アプリを開発するときには、おうおうにして行うというか、そのほうがいいと推奨するサイトもありますね。

 たとえば、以下なら、オブジェクト名にかかわらず CheckBoxであるかどうかの判定が可能です。

    Dim ctrl As MsForms.Control

    For Each ctrl In Controls
        If TypeName(ctrl) = "CheckBox" Then
            MsgBox ctrl.Name
        End If
    Next

 参考までに、チェックボックスやオプションボタン以外(テキストボックス等)なら以下でもいいのですが
 この方式だと オプションボタンのタイプも MsForms.CheckBox になってしまうので、↑のように TypeNameで判定したほうが
 安全ですね。

    Dim ctrl As MsForms.Control

    For Each ctrl In Controls
        If TypeOf ctrl Is MsForms.CheckBox Then
            MsgBox ctrl.Name
        End If
    Next

(β) 2016/08/11(木) 16:21


 以下のようなコードでも。

    Dim v() As Variant
    Dim ctrl As MSForms.Control
    Dim x As Long

    ReDim v(1 To Controls.Count, 1 To 1)
    Sheets("Sheet1").Range("B17:B21").ClearContents

    For Each ctrl In Controls
        If TypeName(ctrl) = "CheckBox" Then
            If ctrl.Value Then
                x = x + 1
                v(x, 1) = ctrl.Caption
            End If
        End If
    Next

    Sheets("Sheet1").Range("B17").Resize(x).Value = v

(β) 2016/08/12(金) 08:18


既に解決と思われますので、全く別の方法で。
チェックボックス付きのリストボックスを使用します。

リストボックスとコマンドボタンを各1個用意して
以下で試してみてください。

 Option Explicit

 Private Sub CommandButton1_Click()
    Dim i As Long, n As Long

    With Worksheets("Sheet1").Range("B17:B24")
        .ClearContents
        For i = 0 To ListBox1.ListCount - 1
            If ListBox1.Selected(i) Then
                n = n + 1
                .Cells(n).Value = ListBox1.List(i)
            End If
        Next
    End With

 End Sub

 Private Sub UserForm_Initialize()

    With ListBox1
        .List = Array("1-1", "1-2", "1-3", "1-4", _
                        "2-1", "2-2", "2-3", "2-4")
        .MultiSelect = fmMultiSelectMulti
        .ListStyle = fmListStyleOption
    End With

 End Sub

(マナ) 2016/08/13(土) 11:09


 > ユーザーフォーム上のコントロール名をデフォルトから特定のものに変更するということは
 > 実務アプリを開発するときには、おうおうにして行うというか、そのほうがいいと推奨する
 > サイトもありますね。

 おいらは、変更するのが常識と思っていた。ww

 > この方式だと オプションボタンのタイプも MsForms.CheckBox になってしまうので、↑の
 >ように TypeNameで判定したほうが安全

 ベテランでも以外に知らなかったり、忘れていたりする情報、大切だね。w

(とおりすがり) 2016/08/13(土) 14:29


今までご回答いただいた皆様お久しぶりでございます。

夏季休暇中で長らくご返信が遅れてしまい申し訳ありません。

前回ご指摘いただきました「●」を別シートに・・・の部分を自分なりに考えたのですが、惜しいところで躓いてしまいました。
また、ご回答いただいておりました式についての質問もさせていただきたいと思います。

まず一つ目の
>チェックボックスで必要項目選択→セルに記入
この時にボタンを押すと、別シート「集計」に選んだものが黒丸で記入されるということも行いたいです。
(例)チェックボックスで「1-2・1-4」を選択した場合
A   B  C  D  E  F
記号 1-1 1-2 1-3 1-4 1-5
あ      ●     ●

の部分なのですが、自分なりに考えタイトル行を除いた一行目に●を表示させることはできました。
なのですが、二行目以降にも●を表示させようとしたのですが、なぜか空白になってしまいました。

Sub sB17()

    Dim cDim() As String
    Dim iC As Long
    Dim i As Long
    Dim iw As Long
    For i = 0 To Controls.Count - 1
        If 0 < InStr(Controls(i).Name, "CheckBox") Then
            If Controls(i).Value = True Then
                ReDim Preserve cDim(iC)
                cDim(iC) = Controls(i).Caption
                iC = iC + 1
            End If
        End If
    Next i
    Range("B16:J24").ClearContents
    For i = 0 To iC - 1
        Cells(16 + i, "B").Value = cDim(i)
        Cells(16 + i, "I").Value = "1"
        Cells(16 + i, "J").Value = "式"
    Next i
    Worksheets("集計2").Range("B2:J100").ClearContents
    lastRow = Worksheets("集計2").Cells(Rows.Count, "B").End(xlUp).Row + 1
    If CheckBox1.Value = True Then
        Worksheets("集計2").Cells(lastRow, "B").Value = "●"
    End If
    If CheckBox2.Value = True Then
        Worksheets("集計2").Cells(lastRow, "C").Value = "●"
    End If
    If CheckBox3.Value = True Then
        Worksheets("集計2").Cells(lastRow, "D").Value = "●"
    End If
    If CheckBox4.Value = True Then
        Worksheets("集計2").Cells(lastRow, "E").Value = "●"
    End If
    If CheckBox5.Value = True Then
        Worksheets("集計2").Cells(lastRow, "F").Value = "●"
    End If
    If CheckBox6.Value = True Then
        Worksheets("集計2").Cells(lastRow, "G").Value = "●"
    End If
    If CheckBox7.Value = True Then
        Worksheets("集計2").Cells(lastRow, "H").Value = "●"
    End If
    If CheckBox8.Value = True Then
        Worksheets("集計2").Cells(lastRow, "I").Value = "●"
    End If
    If CheckBox9.Value = True Then
        Worksheets("集計2").Cells(lastRow, "J").Value = "●"
    End If
End Sub

こちらが現在使用している式です。

二つ目なのですが、現在使用させていただいている式は上記のものなのですが、こちらに追加で
修正を行いたいです。

つまり、チェックボックスで最初に入力した項目に追加・削除があった場合にもう一度ユーザーフォームを開くと、既に入力されている項目のチェックボックスにチェックが入っており、そこから新たに項目を入力、または削除が行いたいです。

なにとぞ、よろしくお願いいたします。
(ねこ) 2016/08/22(月) 16:26


 > Worksheets("集計2").Range("B2:J100").ClearContents

ここで出力先を消しているので、何回実行しても、毎回1行分しか出力しないかと。
この1行をコメントアウトしてみてください。
(???) 2016/08/22(月) 17:20


>???様、ご回答ありがとうございます。

ご返信が遅くなってしまい申し訳ありません。
ご指摘いただきました部分をコメントにしたところ、今度は黒丸が一つ以上でるという不具合が起きてしまいました。

例:チェックボックス1〜5を順番にチェックした時、別シートの各列1に5つ・2に4つ・3に3つ・4に2つ・5に1つという風に黒丸が出てしまいました。

この場合どのように対応すればよろしいでしょうか?
または、こちらの式では行えないのでしょうか?

よろしくお願いいたします。
(ねこ) 2016/08/24(水) 09:19


sB17というプロシジャですが、これはどこから呼び出していますか? もしかして、チェックのON/OFF時に毎回呼んでます?
プロシジャ内では9つのチェックボックス全てを見ているので、1つチェックした段階で、その1件だけ●になり、2番目と更にチェックすると1番目と2番目が●。1回チェックする度に次の行になるので、


●●
●●●…

というように動いたのでは? そういう風に動くロジックになっています。元は毎回前の値を消していたので、1行だけだっただけ。
例えば、チェックボックスのON/OFFではsB17を呼び出さずに自由にチェックさせておき、別途ボタンを置いておき、これを押した時にsB17を呼び出すようにすれば、1回のボタン押下で1行追加、となります。お望みなのはそういう動きではないでしょうか?
(???) 2016/08/24(水) 09:35


>???様、ご回答ありがとうございます。

>例えば、チェックボックスのON/OFFではsB17を呼び出さずに自由にチェックさせておき、別途ボタンを置いておき、これを押した時にsB17を呼び出すようにすれば、1回のボタン押下で1行追加、となります。お望みなのはそういう動きではないでしょうか?

についてなのですが、申し訳ありません。
まだまだVBAを勉強中の身でして、上記の動作をどう行うのかがわかりません。
上記のような動作を行いたいとき、式をどのように書き換えればよろしいでしょうか?

よろしくお願いいたします。
(ねこ) 2016/08/24(水) 09:57


今使っているチェックボックスのコントロールは、どうやって配置しましたか?

同様に、ActiveXのコマンドボタンを選択して配置。これをダブルクリックして、出てきたプロシジャに、Call sB17 と1行追記するだけですよ。
(同時に、チェックボックスクリック時のプロシジャを書いているならば、削除)
(???) 2016/08/24(水) 10:44


>???様、ご回答ありがとうございます。

Private Sub CheckBox1_Click()
Call sB17
End Sub

Private Sub CommandButton1_Click()
Call sB17
End Sub
に変更したところ、きちんと挙動してくれました。ありがとうございます。

一昨日質問させていただいた2つめの
>つまり、チェックボックスで最初に入力した項目に追加・削除があった場合にもう一度ユーザーフォームを開くと、既に入力されている項目のチェックボックスにチェックが入っており、そこから新たに項目を入力、または削除が行いたいです。

という部分なのですが、どうしてもうまくいきませんでした。
セルの場所が決まっているときの書き方はわかるのですが、セルの場所がランダムなので
どういう定義の仕方をすればいいのかがわかりません。
セル範囲は決まっているので、セル範囲の中からチェックボックスのCaptionに記入している文字列を検索?という風なことは可能なのでしょうか?

何卒、よろしくお願いいたします。
(ねこ) 2016/08/24(水) 10:56


セルの値チェックは、For文でループし、1セルずつ値をイコールで比較する、等で簡単にできますが、現状、チェックのON/OFFを見るならば、●の有無で判断するしかないのでは? そうなると、●が並んだ最下行を得れば良いのですが、必ず入力がある列が存在しないので、ちょっと難しいでしょうね。 なので、サンプルを書いてしまいます。

 Private Sub UserForm_Initialize()
    Dim i As Long
    Dim iR As Long

    With Sheets("集計2")
        iR = .Range("A1", .Cells.SpecialCells(xlLastCell)).Rows.Count
        For i = 1 To 9
            If .Cells(iR, i + 1).Value <> "" Then
                Me.Controls("CheckBox" & i).Value = True
            Else
                Me.Controls("CheckBox" & i).Value = False
            End If
        Next i
    End With
 End Sub
(???) 2016/08/24(水) 11:35

このコードで、ちょっとだけ問題が。
全てのチェックを外した場合、現状だとなにも追記されていないので、最下行が得られません。 つまり、全てチェック無し、にはならないということ。

全てチェック無しの場合があり、その状態に復元したいならば、●に使っていない列で良いので、必ず何らかの値をセットしてください。
(???) 2016/08/24(水) 11:40


>???様、ご回答ありがとうございます。

>必ず入力がある列が存在しないので、ちょっと難しいでしょうね。
の部分なのですが、セルのA列は必ず入力される項目があります(シート名)

また、いただいた式はユーザーフォーム内に貼り付ければよろしいのでしょうか?

いただいた式の意味をすべては理解できていないのですが、
>iR = .Range("A1", .Cells.SpecialCells(xlLastCell)).Rows.Count
の部分の"A1"というのは●の開始位置?ということでしょうか?

質問ばかりで申し訳ありません。
よろしくお願いいたします。
(ねこ) 2016/08/24(水) 11:47


A1は、シートの左上を固定指定しています。そこからデータが入力された事のある終端セルまで、全てを範囲として考えたとき、何行あるか、というのを求めているので、どんなシートの場合でも、とりあえずはA1のままにしてください。

まぁ、そのあたりの工夫が、言っても判ってもらえないと思ったので、実例にした訳です。
(???) 2016/08/24(水) 15:19


>???様、ご回答ありがとうございます。

"A1"のご説明ありがとうございます。

いただいた式を使用してみたのですが、なんの挙動も起きませんでした。
どういった場合にこの挙動が起きてくれるのでしょうか?

よろしくお願いいたします。
(ねこ) 2016/08/24(水) 15:56


UserForm_Initialize()時なので、UserFormを表示したときですが?

コードはUserFormに貼らないと動きません。もしかして、標準モジュールとかシートモジュールに貼っていませんか?
(???) 2016/08/24(水) 16:02


>???様、ご回答ありがとうございます。

いただいた式はUserForm1に貼っています。
しかしなぜかなんの挙動も起きない状況です。

私の理解が足りないせいかもしれません。
よろしくお願いいたします。
(ねこ) 2016/08/24(水) 16:23


当たり前の事ですが、フォームの表示はできて、チェックのON/OFFはできているのですよね?

UserForm_Initializeプロシジャ内でブレークポイントを貼ってから(マクロが書いてある白い部分の左にある灰色の領域をマウスクリックし、茶色の●を付ける)、F5キーで実行するとどうなりますか? プロシジャに飛んできて、止まりますか? プロシジャが動いているけど何もチェックボックスに反映されないのか、それともプロシジャが動いていないのかを切り分けてください。

また、"集計2"シートで、●の書いていない行から下を全部選択し、削除し、ブックを保存。再度ブックを開いてからフォームを開くとどうなりますか?(表示はないけれど、過去に使われた行が存在する可能性)
(???) 2016/08/24(水) 17:03


マクロの編集画面で、左側のツリーにあるUserForm1をダブルクリック。次に右上の2つ並んだコンボボックスから、UserFormとInitializeを選択。これで貼ったコードが表示されるはずですが、どうでしょう? (ものすごく当たり前の事を書いていますが、UserForm_Initializeプロシジャが動かないというのは考えられないもので…)
(???) 2016/08/24(水) 17:08

>???様、ご回答ありがとうございます。

上記のことを試してみたのですが、上のコンボボックスにはきちんと表示されています。
(コンボボックスの左にUserForm、右にInitializeが表示されています)

こちらのコードは動いた際どのような挙動になるのでしょうか?
(チェックボックスにすでにチェックがついた状態になる...?)

無知で本当にすいません。
よろしくお願いいたします。
(ねこ) 2016/08/24(水) 17:15


最後にチェックしてあった時と同じ内容で、チェックボックスがON/OFFしてある状態で表示されますよ。
"集計2"シートに何も過去の●がなければ、何もチェックされない事で正解。

で、F5キーを押しても動かなかったですか?(あり得ないのですが…)
(???) 2016/08/24(水) 17:19


>???様、ご回答ありがとうございます。

いただいた式をそのままコピー&ペーストしたのですが、なにもアクションが起きませんでした。
こちらの式で、もし変更する部分があるとすればシート名が記入してある「"集計2"」の部分だけという認識であっていますでしょうか?

また、こちらの式を使用する場合ユーザーフォームを開く場所はユーザーフォームを使用して作成する表(集計2シート以外)のシートでよろしかったでしょうか?

よろしくお願いいたします。
(ねこ) 2016/08/25(木) 08:48


フォームはシートとは関係ないので、表示しておくシートはどれでも構いません。UserForm1.Show さえ行えばOKです。 まさか、別ブック、ということは無いですよね? いったい何が食い違っているのやら…。

シート名は、前のやりとりで出ていたものですし、違うならばそこでエラー停止するので、問題無いでしょう。
で、ブレークポイントを貼っても飛んで来ないし、F5で実行しても何も起きないし、ですよね?

次は、F8キーでマクロを直接ステップ実行してみてください。これでなにも動きません、というのはあり得ませんので、ループを繰り返したか、どちらの判定になったかを教えてください。
(???) 2016/08/25(木) 09:06


>???様、ご回答ありがとうございます。

使用するブックはひとつだけなので、別ブックは使用していないです。

F8を押してステップ処理を行ったところ
If .Cells(iR, i + 1).Value <> "" Then

                Me.Controls("CheckBox" & i).Value = True
            Else
                Me.Controls("CheckBox" & i).Value = False
            End If
        Next i
の部分がきちんと9回ループされ、10回目にF8を押すとユーザーフォームが起動されました。(ユーザーフォームは何もチェックが入っていない状態で表示されました。)

使用しているユーザーフォームがUserForm4なのがいけないのでしょうか?(いただいた式はUserForm4に貼り付け、sheetからユーザーフォームを呼び出すボタンにもモジュールにUserForm4.Showと記入したものを登録しています。)

よろしくお願いいたします。
(ねこ) 2016/08/25(木) 09:29


9回ちゃんとループはしているということは、動いているけれど結果が何もセットされていない、という事ですね。
UserForm4でも構いません。F8キーで実行して、チェックボックスにセットしている箇所でエラー停止しないということは、チェックボックスも正しく9つ貼ってある、という事でしょう。 OKです。

そうなると問題は、集計2シートの方かと思います。確認のため、もう一度フォームのマクロをF8キー実行し、iR の値をセットしている箇所より後で、iRが幾つになったか調べてください。

次に、集計2シート上で CTRL+SHIFT+END キーを押してみてください。 最後の行は iR の値と同じであることを確認してください。

このとき、範囲指定されている最下行に、●はありますか? 何列でしょうか?(B〜J列のいずれかのはず)
(???) 2016/08/25(木) 09:50


>???様、ご回答ありがとうございます。

iRの値がいくつになっているかは、どの部分で判断すればよろしいのでしょうか?

集計2シートには、現在テストのためのデータが一行だけ入っている状態です。
(●が入っている列は、B・C・D・G・H・Iです。)
(ねこ) 2016/08/25(木) 10:05


ステップ実行して停止状態のときに、変数名部分にマウス移動させると、中身が表示されますよ。
または、イミディエイトウィンドウ上で、? ir とか入力しENTERしてもOK。

CTRL+SHIFT+ENDで、●の入った行は選択されましたかね? ●より下の、何も無い行まで選択されていませんか?
(???) 2016/08/25(木) 10:37


>???様、ご回答ありがとうございます。

CTRL+SHIFT+ENDを行ったところ、A1〜J72まで選択されました。

iRの値も見てみると、iR=72と表示されました。
集計2のセル自体には、2行目以降にデータは入っていないのですが、こちらはどう対処すればよろしいでしょうか?

よろしくお願いいたします。
(ねこ) 2016/08/25(木) 10:44


前にちょっと書いたのですが、2行目〜72行目(多めでOK)をまとめて行選択。右クリックして行削除。そして一旦保存してから、ブックを開き直してみてください。
(過去に72行目に何か入力し、それを消した事があるのだと思われます)

開き直した後、またCTRL+SHIFT+ENDを試してみて、1行目だけ選択されるならば、フォームのチェックボックスにも反映されるでしょう。
(???) 2016/08/25(木) 11:29


>???様、ご回答ありがとうございます。

上記の方法で試してみたところ、一度入力したものがきちんとチェックボックスに反映されました。
しかし、本当に申し訳ないのですが、私が思い描いていた結果とはすこし違うものでした。

チェックボックスに反映される部分は思い描いた通りのものだったのですが、修正をしようとした際
集計2をみると、修正前の結果の下の行に修正後の結果が出てしまいました。

修正前の結果の上に修正後の結果を反映させることは可能でしょうか?
過去に質問させていただいた際に、下記の式をいただいたのですが、こちらを???様の式に組み込むことは可能でしょうか?
こちらの式は、修正を行う際に集計2シートのA列に記入されているシート名をみて、、、というものです。

   Dim RowToFix As Long

   Dim shTofix As Worksheet
   Dim strShName As String
     strShName = UserForm2.TextBox1
     Set shTofix = Worksheets(strShName)

   RowToFix = Application.Match(strShName, .Columns("A"), 0)

         .Cells(RowToFix, "A") = shTofix.Range("A1").Value

よろしくお願いいたします。
(ねこ) 2016/08/25(木) 12:01


A列には、テキストボックスと一致する文字列を記入してあった訳ですね。最下行、意味なかったですか…。
そうなると、かなり変わります。変更箇所を全部説明するのは面倒なので、まとめてコードで。

 Private Sub TextBox1_Change()
    Call sGetChk
 End Sub

 Private Sub UserForm_Initialize()
    Call sGetChk
 End Sub

 Private Sub CommandButton1_Click()
    Call sSetChk
 End Sub

 Sub sGetChk()
    Dim i As Long
    Dim iR As Long

    With Sheets("集計2")
        For iR = 1 To .Cells(.Rows.Count, "A").End(xlUp).Row
            If TextBox1.Text = .Cells(iR, "A").Value Then
                Exit For
            End If
        Next iR
        For i = 1 To 9
            If .Cells(iR, i + 1).Value <> "" Then
                Me.Controls("CheckBox" & i).Value = True
            Else
                Me.Controls("CheckBox" & i).Value = False
            End If
        Next i
    End With
 End Sub

 Sub sSetChk()
    Dim i As Long
    Dim iR As Long

    With Sheets("集計2")
        For iR = 1 To .Cells(.Rows.Count, "A").End(xlUp).Row
            If TextBox1.Text = .Cells(iR, "A").Value Then
                Exit For
            End If
        Next iR
        .Cells(iR, "A").Value = TextBox1.Text

        For i = 1 To 9
            If Me.Controls("CheckBox" & i).Value = True Then
                .Cells(iR, i + 1).Value = "●"
            Else
                .Cells(iR, i + 1).Value = ""
            End If
        Next i
    End With
 End Sub
(???) 2016/08/25(木) 13:22

>???様、ご回答ありがとうございます。

申し訳ありません、上記で記入してあるテキストボックスというのは他のユーザーフォームでの作業の中で使用していたもので、今回のユーザーフォームには使用していませんでした。

なので、チェックボックスで項目を入力するシートのA1に集計2シートのA列と一致するものが記入されているので、TextBox1.Textの部分をRange("A1")に変更いたしました。
また、上記の式をそのまま貼り付けると、「Private Sub CommandButton1_Click()」の部分でエラーが出てしまいました。(Private Sub CommandButton1_Click()がすでに存在したためだと思われます)
なので、新たなボタンを作成し、「Private Sub CommandButton2_Click()」に「Call sSetChk」を貼り付けたのですが、こちらがまずかったでしょうか?

そのせいなのかわからないのですが、今度は集計2シートにはきちんと行いたかった修正ができたのですが、チェックボックスで入力した項目が修正されなくなってしまいました。

長々と申し訳ありません。
何卒よろしくお願いいたします。

(ねこ) 2016/08/25(木) 13:58


同じプロシジャが2つあると動かないのは当たり前の事ですので、その辺はご自身で解決していただかないと…。

元のUserForm4にあったコードは全て消した上で、私の書いたコードを貼ってください。(ブックのコピーを取っておけば、何があっても戻せますよね) その後、TextBox1部分はRange参照に変更。TextBox1_Changeプロシジャは使われないでしょうから、削除。 それで正しく動くか確認してみてください。

うまく行かない場合は、午前中と同じように、ブレークポイントを張って途中で止めて、変数の値を確認してみてください。特にiRの値は、●を書き込んである行と一致していますか?

ちなみに、sSetChk()プロシジャ内で、.Cells(iR, "A").Value = TextBox1.Text としている行は、シートにない文字列を入力された場合は新しい行を自動作成するためのものでした。 TextBox1が存在しないならば、この行は削除してください。(ここでエラー停止しませんでしたか?)
(???) 2016/08/25(木) 14:31


>???様、ご回答ありがとうございます。

一度すべての式を削除し、いただいた式のみを貼り付けてみたのですが、やはり表示されませんでした。

こちらのおおもとの式をいただいた式の中に組み込めばよろしいのでしょうか?

Sub sB17()

    Dim cDim() As String
    Dim iC As Long
    Dim i As Long
    Dim iw As Long
    For i = 0 To Controls.Count - 1
        If 0 < InStr(Controls(i).Name, "CheckBox") Then
            If Controls(i).Value = True Then
                ReDim Preserve cDim(iC)
                cDim(iC) = Controls(i).Caption
                iC = iC + 1
            End If
        End If
    Next i
    Range("B16:J24").ClearContents
    For i = 0 To iC - 1
        Cells(16 + i, "B").Value = cDim(i)
        Cells(16 + i, "I").Value = "1"
        Cells(16 + i, "J").Value = "式"
    Next i

    lastRow = Worksheets("集計2").Cells(Rows.Count, "B").End(xlUp).Row + 1
    If CheckBox1.Value = True Then
        Worksheets("集計2").Cells(lastRow, "B").Value = "●"
    Else
        Worksheets("集計2").Cells(lastRow, "B").Value = ""
    End If
    If CheckBox2.Value = True Then
        Worksheets("集計2").Cells(lastRow, "C").Value = "●"
    End If
    If CheckBox3.Value = True Then
        Worksheets("集計2").Cells(lastRow, "D").Value = "●"
    End If
    If CheckBox4.Value = True Then
        Worksheets("集計2").Cells(lastRow, "E").Value = "●"
    End If
    If CheckBox5.Value = True Then
        Worksheets("集計2").Cells(lastRow, "F").Value = "●"
    End If
    If CheckBox6.Value = True Then
        Worksheets("集計2").Cells(lastRow, "G").Value = "●"
    End If
    If CheckBox7.Value = True Then
        Worksheets("集計2").Cells(lastRow, "H").Value = "●"
    End If

    If CheckBox8.Value = True Then
        Worksheets("集計2").Cells(lastRow, "I").Value = "●"
    End If
    If CheckBox9.Value = True Then
        Worksheets("集計2").Cells(lastRow, "J").Value = "●"
    End If
End Sub

質問ばかりで本当に申し訳ありません。
よろしくお願いいたします。
(ねこ) 2016/08/25(木) 14:46


まだ表示されなかったとの事ですが、iRの値は幾つでしたか? そこが大事なのですが。
というか、対象行が固定なら、iR = 2 とか、固定にするだけですよ?

sB17は、元のようにCallしてください。 ただし、●を付ける部分はsSetChkプロシジャ内で行っていますので、lastRow に代入している行以下は消してください。(元のロジックだと、最下行の次の行に書き込みます。このコードのせいで、最終行の次にチェック状態を残したいのだと思った訳ですが、違うのですよね)

sB17を復活させるのは、チェックボックスが思ったように動作した後にしないと、また余計ごちゃごちゃしたコードになって、ミスの原因がわからなくなりますよ?
(???) 2016/08/25(木) 14:59


コメント返信:

[ 一覧(最新更新順) ]


YukiWiki 1.6.7 Copyright (C) 2000,2001 by Hiroshi Yuki. Modified by kazu.