[[20111226175037]] 『ユーザーフォームのコントロールの連動』(雪だるま) ページの最後に飛ぶ

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

 

『ユーザーフォームのコントロールの連動』(雪だるま)

 商品の月毎の入荷マスターがあり、そこにユーザーフォームで入荷内容を入力するものを作っています。

 TextBox6 に「在庫ID」を入力したら、それまでに入力されたマスターの履歴から、TextBox7に自動で商品名を表示させたいです。
 (「在庫ID」「商品名」は非常に種類が多く、月毎に追加更新があるのでマスターとして整理できないのです)

 具体的には、マスターのO列に「在庫ID」、P列に「商品名」があります。
 これを、ユーザーフォームのTextBox6に「在庫ID」を入力した時点で、一致するものがあれば
 VLOOKUPで検索するような形でTextBox7に商品名が出るようにしたいと思っています。
 ただし「在庫ID」と「商品名」は必ずしもユニークで繋がっているわけではないので、
 (1対1のものと1対多のものがある)TextBox7に表示させた内容が違っていたらその場で編集できるようにしたいです。
 そしてユーザーフォームに全ての内容を入力した後、最終行にそれを追加するような形で…

 このTextBox6とTextBox7を連動させるような方法はありますでしょうか?

 Excel2007、Windows7です。
 よろしくお願いいたします。


このTextBox6とTextBox7を連動させるような方法はありますでしょうか?

 在ります

 ただ以下の事が気に成ります

 >ただし「在庫ID」と「商品名」は必ずしもユニークで繋がっているわけではないので、
 >(1対1のものと1対多のものがある)TextBox7に表示させた内容が違っていたらその場で編集できるようにしたいです。

 編集とは、入荷マスターの既存のレコードの事を言っているのですか?
 また、

 >そしてユーザーフォームに全ての内容を入力した後、最終行にそれを追加するような形で…

 とは、入荷マスタに新規にレコードを追加すると言う事でしょうか?
 其の時、前回の質問に出ていた「入荷ID」は新規に降り出すのでしょうか?

 (Bun)


 BUN様

 ありがとうございます。

 >編集とは、入荷マスターの既存のレコードの事を言っているのですか?
 既存のレコードを呼び出して、内容が違っていたら書き換えて新規登録(既存のものは変更しない)という感じです。
 説明が下手ですみません。
 あくまで新規レコード追加にあたっての作業でして、既存のものを変えることはありません。
 ただ長い商品名があってその都度入力するのは手間がかかるし、人によって商品名のカタカナや英数字部分を
 全角や半角ごちゃまぜに登録したりするので少しでも入力を統一化できればと思いまして…

 >入荷マスタに新規にレコードを追加すると言う事でしょうか?
 はい、そうです。
 入荷IDは今のところ最初からワークシートに2000行ほど入力されています。
 (B列以降のデータが入っていない分も含めて)
 なのでB列の最終行の次に新しいデータを追加するような形です。

 (雪だるま)

 「TextBox6とTextBox7を連動させる」と言うピンポイントの事象にだけ答えれば善いのだろうけど?
 根が御節介な物で、在庫の入力と言う事が気に掛かりましたので、私だったらこんな事をしますと言う所で?
 (実際にコードを起こして見ないと、色々な問題点が出て来ると思いますが?、思い付きで書きます)

 1、入力と言うのが現在庫の更新、新規レコードの追加と捉える
 2、「入荷マスタ」の列数は30列?位在る
 3、「在庫ID」と「商品名」は1対1では無い
 4、「入荷ID」と言う項目が有り、「入荷マスタ」のレコードは、この項目がユニークで昇順整列されている
 5、新規入力は、「入荷マスタ」のレコードのフィールド(列)全てでは無く一部だけである?

 と勝手に条件を決めて掛かります

 1、「更新用」と言うシートを作成します
  「入荷マスタ」を直接扱うと色々不便不都合が出て来そうなのと、「在庫ID」と「商品名」を連動する為に
 2、「更新用」シート、3行目B列〜?列まで入力項目の列見出しを設定(B列は「入荷ID」、C列は「在庫ID」、D列は「商品名」とする)
  フィルタオプションを使って抽出する為の、抽出範囲として使用
 3、「更新用」シート、1行目B列〜?列までに列見出しに対応する、列位置を「入荷ID」を1列目として設定
  「入荷マスタ」のレコード更新を行う為の代入先位置とする為
 4、?+2列目を条件範囲とする為、3行目?+2列目に「在庫ID」の列見出しを設定
 5、UserFormの入力用TextBoxとは別に、抽出条件とする「在庫ID」を入れるTextBoxを用意する(例、TextBox1とする)
 6、TextBox1に抽出条件とする「在庫ID」を入力して、フォーカスが移動すると、「更新用」シートに「入荷マスタ」の該当する「在庫ID」のレコードが抽出される
 7、CommandButton等で「更新用」シートのレコードを1レコードづつUserFormに表示(CmmandButtonは→←の様に)
 8、更新するレコードをUserFormに表示したら、該当項目を更新し更新ボタン(CommandButton)を押す
 9、「更新用」シートの該当レコードの該当項目の値を変更し、「更新用」シートのA列に更新マーク(*等)を代入
 10、此れを更新が有る迄繰り返しす
 11、新規レコード追加の場合は、「入荷ID」のTextBoxだけを""にして更新ボタン(CommandButton)を押す
  「入荷ID」のTextBoxが""の場合「更新用」シートの最終レコードの後ろに新規レコードが追加される
  また、この場合もA列にマークを入れる
 12、全てが終わったら、UserFormを閉じる
 13、UserFormが閉じるタイミングで、「更新用」シートのA列とB列を上から見て行って、A列にマークの在る物に就いて
  「入荷マスタ」の「入荷ID」をMatch関数等で探し、見つかったレコードを更新
  「更新用」シートの「入荷ID」が未記入の場合、新規レコードとして「入荷マスタ」の「入荷ID」最終値+1で  採番して「入荷マスタ」の最終レコードの後ろに追加される
 14、「更新用」シートの全レコードに就いて処理が終わったら、「更新用」シートのレコードを消去して終了

 概略でこんなかな?

 (Bun)


 BUN様ありがとうございます。

 今自宅なので細かい部分は明日職場でもう一度見てみますが、こちらの説明不足を補足いたします。

 この入荷マスターは
 1.入荷予定を入力
 2.入荷したら実際に入荷した数、使用期限など細かい情報を追加
 ここで1で入力した商品に複数の使用期限があった場合は枝番を作成(前回の「入荷受付ID」にあたる部分)
 なので予定入力より1商品の行数が増える場合もある(その場合、それ以降の商品の入荷IDが予定入力時からずれることがある)
 3.実際に入荷した数を元に前回質問させていただいた「投入表」などの帳票を作成

 こういう流れになっておりまして、今回のユーザーフォームでは「1」の部分を入力するために13項目ほどの
 コントロールをユーザーフォームに配置しています。
 なので過去の在庫の更新などはありません。
 (入荷予定のみなので)
 「2」の実際に入荷した部分はワークシートに直接打ち込んだ方が分かり易いので…(枝番の作成などもあるので)
 本当は「1」自体もベタ打ちの方がオートフィル機能などが使えて良いのですが、上から一応ユーザーフォームを
 用意するように言われて今作っているところです。

 何かわかりにくくてすみません

 (雪だるま)

 そう言う事でしたか
 成らば、「在庫ID」から「商品名」が解れば善いと言う事ならもっと簡単に出来ると思いますよ
 同じ、「在庫ID」で「商品名」が幾つかあり、新規レコードを作成する時に、その一つを編集して使うと言う事なら
 「 入荷マスタ」からDictionaryで「商品名」を無重複で取ってきて、TextBoxでは無くComboBoxで表示、編集する事も難しくは無いと思いますよ

 (Bun)


 TextBox6の値が変わると、ComboBox1のListが変更される例です
 ComboBox1のTextBox部は変更が出来るので、編集して登録が出来ます

 以下、UserFormのコードモジュールに記述して下さい

 Option Explicit

 'Dictionaryをモジュールレベルの変数として宣言
 Private dicIndex As Object

 Private Sub UserForm_Initialize()

    'Dictionaryオブジェクトを取得
    Set dicIndex = CreateObject("Scripting.Dictionary")

 End Sub

 Private Sub UserForm_Terminate()

    'Dictionaryオブジェクトを破棄
    Set dicIndex = Nothing

 End Sub

 Private Sub TextBox6_BeforeUpdate(ByVal Cancel As MSForms.ReturnBoolean)

    Dim i As Long
    Dim lngRows As Long
    Dim vntMark As Variant
    Dim vntData As Variant

    ComboBox1.Text = ""

    With ActiveSheet.Range("A3")
        '行数の取得(B列最終行)
        lngRows = .Offset(Rows.Count - .Row, 1).End(xlUp).Row - .Row
        If lngRows <= 0 Then
            ComboBox1.Clear
            Exit Sub
        End If
        'O、P列データを配列に取得
        vntData = .Offset(1, 14).Resize(lngRows + 1, 2).Value
    End With

    vntMark = TextBox6.Value
    For i = 1 To lngRows
        'O列の値がTextBox6の値と等しいなら
        If vntData(i, 1) = vntMark Then
            'DictionaryにP列の値をKeyとして登録
            dicIndex.Item(vntData(i, 2)) = Empty
        End If
    Next i

    'Dictionryに登録が有ったなら
    If dicIndex.Count > 0 Then
        vntData = dicIndex.Keys
        With ComboBox1
            'ComboBoxにP列を登録
            .List = vntData
            '先頭行を表示
            .ListIndex = 0
        End With
    Else
        ComboBox1.Clear
    End If

    dicIndex.RemoveAll

 End Sub

 (Bun)


 BUN様ありがとうございます!

 これなら商品名はコンボボックスの方が一覧が取得できてよいですね。
 助かりました。
 ありがとうございました。

 (雪だるま)

コメント返信:

[ 一覧(最新更新順) ]


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