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

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

ただいまの
回答率

89.12%

入力フォームのテキストボックスで、Enabledの設定をしたい

解決済

回答 3

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 1,004

jimunomado

score 19

前提・実現したいこと

VBAで以下のような入力フォームを作ろうとしています。

作成中入力フォームイメージ

やろうとしていることは以下の通りです。
①性別を選択するまで男性用、女性用テキストボックスはEnabledにしたい
②性別で、男性が選択されたら男性用と書かれたテキストボックスのみが入力可能になるようにしたい。逆に女性が選択されたら、女性用と書かれたテキストボックスのみが入力可能になるようにしたい。

困っていること

①を実施したいのに、テキストボックスがEnabledにならない
②男性を選択しても女性用テキストボックスも入力可能である

ソースコード

Option Explicit

Private sex As String
Private lastRow As Long

Private Sub UserForm1_Initialize()
TextBox3.Enabled = False '男性用テキストボックス
TextBox4.Enabled = False '女性用テキストボックス


End Sub


Private Sub CommandButton1_click()

With Worksheets("Sheet1")
    lastRow = .Cells(Rows.Count, 1).End(xlUp).Row + 1
    .Cells(lastRow, 1).Value = TextBox1.Text '名前
    .Cells(lastRow, 2).Value = sex '性別選択オプションボックス
    .Cells(lastRow, 3).Value = TextBox3.Text
    .Cells(lastRow, 4).Value = TextBox4.Text
End With

TextBox1.Text = ""
male.Value = False
female.Value = False
TextBox3.Text = ""
TextBox4.Text = ""

End Sub

Private Sub Male_Change()
    If male.Value = True Then
        sex = "男性"
    End If
End Sub

Private Sub Male_Change2()
    If male.Value = True Then
        TextBox3.Enabled = True
        TextBox4.Enabled = False

    End If
End Sub

Private Sub Female_Change2()
    If female.Value = True Then
        TextBox3.Enabled = False
        TextBox4.Enabled = True
    End If
End Sub

Private Sub Female_Change()
    If female.Value = True Then
        sex = "女性"
    End If
End Sub

試したこと

ユーザーフォームのプロパティウィンドウから、TextBox3とTextBox4のEnabledオプションをFalseにしてみましたが、そうすると性別選択をしても入力フォームは完全に入力できない状態になります。
あとは

Private Sub Male_Change()
    If male.Value = True Then
        sex = "男性"
    End If
End Sub

Private Sub Male_Change2()
    If male.Value = True Then
        TextBox3.Enabled = True
        TextBox4.Enabled = False

    End If
End Sub

Private Sub Female_Change2()
    If female.Value = True Then
        TextBox3.Enabled = False
        TextBox4.Enabled = True
    End If
End Sub

Private Sub Female_Change()
    If female.Value = True Then
        sex = "女性"
    End If
End Sub


の入力位置も気になっているのですが、もしこれが間違っているとしてじゃあどこに入力したら適切??となっています……。

操作環境他

Excel2010、Win7 64bit版で操作しています。
また当方VBAを独学で学んでいる初心者です。初歩的なところで間違いなどしているかと思います。
どうぞお手柔らかにお願いいたします。

お礼と最終的なコード

皆様ご回答いただきありがとうございました。大変勉強になりました。
ベストアンサーはhatena19さまにさせていただきました。
皆様のアドバイスを参考に、以下のようなコードになりました。
※2019/01/25追記:コードに誤りがあったため下記修正いたしました。コメントアウトにて修正箇所記入しております。

Option Explicit

Private sex As String
Private lastRow As Long

Private Sub UserForm_Initialize()
'UserForm1・・・という書き方をしていたのですが、こちらが誤りであると別質問をした際に気が付きました。
    TextBox3.Enabled = False
    TextBox3.BackColor = &HC0C0C0
    TextBox4.Enabled = False
    TextBox4.BackColor = &HC0C0C0
End Sub


Private Sub CommandButton1_click()

With Worksheets("Sheet1")
    lastRow = .Cells(Rows.Count, 1).End(xlUp).Row + 1
    .Cells(lastRow, 1).Value = TextBox1.Text
    .Cells(lastRow, 2).Value = sex
    .Cells(lastRow, 3).Value = TextBox3.Text
    .Cells(lastRow, 4).Value = TextBox4.Text
End With

TextBox1.Text = ""
male.Value = False
female.Value = False
TextBox3.Text = ""
TextBox4.Text = ""
TextBox5.Text = ""

End Sub


Private Sub male_click()
    sex = "男性"
    TextBox3.Enabled = True
    TextBox4.Enabled = False
    TextBox3.BackColor = &HFFFFFF
    TextBox4.BackColor = &HC0C0C0
End Sub

Private Sub female_click()
    sex = "女性"
    TextBox3.Enabled = False
    TextBox4.Enabled = True
    TextBox4.BackColor = &HFFFFFF
    TextBox3.BackColor = &HC0C0C0
End Sub


当初希望していた「オプションボタンで選択するまではテキストボックスはEnabled.Falseにしたい」という点は、よくよく考えたところ必要ないことがわかりましたので、実装しないことにしました。
またEnabled.Falseにしたテキストボックスについては、背景色をグレーにすることにしました。

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 3

checkベストアンサー

+2

通常は男と女のどちらか一方だけ選択できるようにすると思いますので、その場合は、フレーム内にオプションボタンを配置するとグループ化されてその中一つだけが選択できるようになります。

Excel VBA フレームを使用してオプションボタンをグループ化する

その場合、オプションボタンのChangeイベントは、一つのオプションボタンを選択すると他のオプションボタンでも発生してしまいます。
そこで、Clickイベントを使うとコードがシンプルになります。

Option Explicit
Private sex As String

Private Sub UserForm1_Initialize()
    TextBox3.Enabled = False  '男性用テキストボックス
    TextBox4.Enabled = False  '女性用テキストボックス
End Sub

Private Sub male_Click()
    sex = "男性"
    Me.TextBox3.Enabled = True
    Me.TextBox4.Enabled = False
End Sub

Private Sub female_Click()
    sex = "女性"
    TextBox3.Enabled = False
    TextBox4.Enabled = True
End Sub

Private Sub CommandButton1_click()
    With Worksheets("Sheet2").Cells(Rows.Count, 1).End(xlUp)
        .Offset(1, 0).Value = TextBox1.Text '名前
        .Offset(1, 1).Value = sex  '性別選択オプションボックス
        .Offset(1, 2).Value = TextBox3.Text
        .Offset(1, 3).Value = TextBox4.Text
    End With

    TextBox1.Text = ""
    male.Value = False
    female.Value = False
    TextBox3.Text = ""
    TextBox4.Text = ""
    TextBox3.Enabled = False
    TextBox4.Enabled = False
End Sub

イメージ説明


オプションボタンのグループ化について補足しておきます。

オプションボタンというのは名前の通り、複数の選択肢から一つを選択するためのものです。
単独で、On/Offの切り替えとして使うこともできますが、そういう用途の場合はチェックボックスを使うのがWindowsでの標準のUIです。

今回は、男か女のどちらか一方しか選択できないようにすべきなので、
それをコードで実現するなら、「男」が選択されている状態で「女」を選択したら、「男」の選択が解除されるようにコーディングする必要があります。

しかし、グループ化すればそのようなコードは不必要になります。オプションボタンのグループ化の方法は2つあり、今回の回答のようにフレーム上に配置する方法と、オプションボタンのGroupNamプロパティに共通のグループ名を設定する方法があります。
フレームでグループ化するとFor Eachでフレーム上のコントロールを参照できるのでこちらの方が使い勝手がいいかと思います。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/01/22 20:03

    ありがとうございます!こんな書き方もあるのですね、、、。
    ところでcellsプロパティとこのoffset……何か違いはありますでしょうか?恥ずかしながら、offsetなるものを初めて見たのです(-_-;)

    キャンセル

  • 2019/01/22 20:30

    cellsだと lastRow という最終行を格納する変数が必要になりますが、
    Offsetを使えば不要になり若干コードがシンプルになります。
    あと、基準列が変更になった場合(現状は1列目からですが、2列目からデータとなったりなど)、修正個所が1か所ですみます。
    ということで、私はOffsetを多用します。
    まあ、その辺は好みの問題ですので、読みやすいと思う方を選択すればいいかと思います。

    キャンセル

  • 2019/01/23 10:14

    ちょっと横から失礼してcellsとoffsetについて補足させてください。m(__)m

    ・`Cells`は行番号・列番号を指定する「絶対座標指定」
    ・`Offset`は基準となるセル(今回の場合A列最終行)からみた行・列のズレを指定する「相対座標指定」

    使い分けを考える際は、ここが原点になると思います。

    hatena19さんの言うとおり基本的にどちらを使うかは好みの問題ではありますが、`Offset`の方がコーディング的に便利な場面が多いです。
    反面、パッとみて「どこを指しているのかわかりにくい」というデメリットもあります。

    今回の「最終行の下に出力」といった具合に、変動する基準セルに応じて位置が決まるような場面では`Offset`の方が効率的です。
    しかし毎回決まった位置(固定座標)を指定するなら、`Cells`や`Range`で記述したほうが可読性がよくなります。

    基本的に自分が記述する際は上記のような判断基準でどちらにするか決定しています。

    可読性の話なので、最終的には周辺のコードの書きっぷりや好みによるところも大きくなりますし、場合によっては「固定座標でもOffsetの方がみやすい(わかりやすい)」ということもあるのですが、大枠はそんなところです。

    参考になれば幸いです。

    キャンセル

  • 2019/01/23 10:22

    お二方ともありがとうございます!そんな違いがあるのですね、、、。わかりやすい説明をありがとうございます。

    キャンセル

0

二つのChange2プロシージャが実行されていないからでは?
そんなイベントはないので、Changeプロシージャから呼ぶか、処理内容をChangeプロシージャ内に記述しましょう。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/01/22 16:31

    わー!そこはみおとしておりました、、、。

    キャンセル

0

①性別を選択するまで男性用、女性用テキストボックスはEnabledにしたい

UserForm1_Initializeで、両テキストボックスをfalseにしてるから。

②性別で、男性が選択されたら男性用と書かれたテキストボックスのみが入力可能になるようにしたい。逆に女性が選択されたら、女性用と書かれたテキストボックスのみが入力可能になるようにしたい。

Change2というイベントはありません。
ChangeイベントにChange2の中身を移せばよいと思います。

Private Sub Male_Change()
    If male.Value = True Then
        sex = "男性"
        TextBox3.Enabled = True
        TextBox4.Enabled = False
    End If
End Sub

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/01/22 16:41 編集

    大変わかりやすい回答をありがとうございました!やりたいことができました。

    キャンセル

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

  • ただいまの回答率 89.12%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる