Excel VBA質問箱 IV

当質問箱は、有志のボランティア精神のおかげで成り立っています。
問題が解決したら、必ずお礼をしましょうね。
本サイトの基本方針をまとめました。こちら をご一読ください。

投稿種別の選択が必要です。ご注意ください。
迷惑投稿防止のため、URLの入力を制限しています。ご了承ください。


7757 / 13645 ツリー ←次へ | 前へ→

【36945】同型のフォームで似たような処理・・・・ もんこち 06/4/18(火) 19:24 質問[未読]
【36959】Re:同型のフォームで似たような処理・・・・ ichinose 06/4/19(水) 8:54 発言[未読]
【37028】Re:同型のフォームで似たような処理・・・・ もんこち 06/4/19(水) 22:56 質問[未読]
【37040】Re:同型のフォームで似たような処理・・・・ ichinose 06/4/20(木) 8:21 発言[未読]
【37075】Re:同型のフォームで似たような処理・・・・ もんこち 06/4/20(木) 20:28 質問[未読]
【37083】Re:同型のフォームで似たような処理・・・・ ichinose 06/4/20(木) 22:55 発言[未読]

【36945】同型のフォームで似たような処理・・・・
質問  もんこち  - 06/4/18(火) 19:24 -

引用なし
パスワード
   みなさんこんばんわ。
いつも勉強させていただいています。

今回商品名の頭数文字を入力すると該当する商品をListboxに表示し、同時に単価や単位、購入価、売価などの情報を取得するフォームを作成しました。

商品種類ごとに購入価が必要だったり売価が必要だったりするので現状では種類の数だけ同じようなフォームを作って取得するセル位置だけを変えたコードを何度もかいているのです。(効率が悪いなぁ><)

そこで上級者の方御用達!!wクラスモジュールなら引数によって取得する位置を変更してくれたりするのでは・・・と思ったりしまして書き込みをしています。

クラスモジュールに検索、Listboxに追加、他の値の取得などのコードを書いて、フォームには、

sub ***()
  クラス呼出(引数ちゃん)
end sub

という感じで動的な処理ができないかなぁと夢見ています。

みなさま知恵をお貸しください。。。

【36959】Re:同型のフォームで似たような処理・・...
発言  ichinose  - 06/4/19(水) 8:54 -

引用なし
パスワード
   ▼もんこち さん:
おはようございます。
>今回商品名の頭数文字を入力すると該当する商品をListboxに表示し、同時に単価や単位、購入価、売価などの情報を取得するフォームを作成しました。
>
>商品種類ごとに購入価が必要だったり売価が必要だったりするので現状では種類の数だけ同じようなフォームを作って取得するセル位置だけを変えたコードを何度もかいているのです。(効率が悪いなぁ><)
この同じようなフォームというのがどの程度同じなのかわかりませんが、
コントロールの種類や数に変更がないならば
(いえ、あってもその程度にもよりますが)

ユーザーフォーム自体に情報を送るという方法を検討されてみては
いかがですか?

といっても、

Userform1.show(引数)

という記述はできませんから、別の方法を考えなければなりませんが、

Public変数を使用すれば、ユーザーフォームに情報の伝達は可能です。

ユーザフォームに情報さえ伝達できれば、その情報を基に処理を
変更するようなコードが記述できることになります。


>クラスモジュールなら引数によって取得する位置を変更してくれたりするのでは・・・と思ったりしまして書き込みをしています。
>
>クラスモジュールに検索、Listboxに追加、他の値の取得などのコードを書いて、フォームには、
>
>sub ***()
>  クラス呼出(引数ちゃん)
>end sub
読ませていただいた内容からですと、↑この必要性はないように
思いますが・・・。


具体的な方法については、
もう少し詳しい情報が必要かもしれませんよ!!

何をなさりたいかを具体例を提示して
記述してみてください。

【37028】Re:同型のフォームで似たような処理・・...
質問  もんこち  - 06/4/19(水) 22:56 -

引用なし
パスワード
    レスありがとうございます。

フォームが4つ(frmBaika,frmNounyuuka,frmRevBaika,frmRevNounyuu)ありまして、すべてのフォームで以下のようなコードを書いています。

'==========================================================================
'=オートフィルタを使ってリストへ候補表示=======================================
Private Sub TextBox1_Exit(ByVal Cancel As MSForms.ReturnBoolean)


Application.ScreenUpdating = False
 
 
  '=オブジェクト変数のセット=
  Set wbOwn = ThisWorkbook
  Set wsDrugMaster = wbOwn.Worksheets("商品マスター")
  Set wsSlip = wbOwn.Worksheets("伝票")
 
 
  '=検索キーが空白の時は何もしない=
  If TextBox1 = "" Then
   
   Exit Sub
  
  End If
  
  
  '=検索キーでオートフィルターを実行し結果をリストボックスに表示する=
  wsDrugMaster.Activate
  
  strDrugName = TextBox1.Value
  
  wsDrugMaster.Cells(1, "A").AutoFilter
  
  wsDrugMaster.Columns("HD:HD").Clear
  
  wsDrugMaster.Cells(1, "A").AutoFilter Field:=1, Criteria1:="=" & strDrugName & "*"
  
  wsDrugMaster.Range(wsDrugMaster.Cells(2, "B"), wsDrugMaster.Cells(2, "B").End(xlDown)).Copy
  
  wsDrugMaster.Cells(2, "HD").PasteSpecial
  
  ListBox1.List = wsDrugMaster.Range(wsDrugMaster.Cells(2, "HD"), _
  wsDrugMaster.Cells(2, "HD").End(xlDown)).Value
  
  Application.CutCopyMode = False
  
  
  '="伝票"シートに戻る=
  wsSlip.Select
  
  Range("A1").Select
  
  
  '=リストボックスの最初の項目を選択=
  ListBox1.ListIndex = 0


Application.ScreenUpdating = True


End Sub

'==============================================================================
'選択された医薬品の単価をTB2へ(小数点第2位を四捨五入)==========================
'==============================================================================
Private Sub ListBox1_Click()


  '=変数の宣言=
  Dim rgDrugPhonetic As Range  '"商品マスター"シート半角カナ列(検索範囲)
  Dim rgKana As Range
    
  
  '=オブジェクト変数のセット=
  Set rgDrugPhonetic = wsDrugMaster.Range(wsDrugMaster.Cells(2, "B"), _
    wsDrugMaster.Cells(2, "B").End(xlDown))
  Set wsSlip = wbOwn.Worksheets("伝票")
  
  
  '=項目が選択されていない場合はなにもしない=
  strDrugName = ListBox1.Value
  
  If strDrugName = "" Then
    
    Exit Sub
  
  End If
  
  
  '=選択された項目名をキーに単価・単位(購入価/薬価倍率)を取得する=
  For Each rgKana In rgDrugPhonetic
          
    If rgKana.Value = strDrugName Then
      
      wsSlip.Cells(7, "BH") = rgKana.Offset(0, 4) / rgKana.Offset(0, 2)
      
      dblCost = wsSlip.Cells(7, "BI").Value
      
      strUnit = rgKana.Offset(0, 3)
      
      '=選択された項目の名前・単価・単位を表示する=
      Label12.Caption = strDrugName         
      
      Label9.Caption = strUnit
      
      TextBox2.Value = Format(dblCost, "#,##0.00")
        
    End If
  
  Next rgKana
    

End Sub


フォームによって'=選択された項目の名前・単価・単位を表示する=の部分ひっぱってくるセル位置やセルに転記する場所が少し違うだけなので全部のシートにずらずらーっと書くのは無駄だなぁと思ったんです。
クラス化は必要ないのかもしれないですが、今後のために覚えたいという気持ちもあります・・・
よろしくお願いします。

【37040】Re:同型のフォームで似たような処理・・...
発言  ichinose  - 06/4/20(木) 8:21 -

引用なし
パスワード
   ▼もんこち さん:
おはようございます。


まだ、私にはよくわかりません。


>フォームが4つ(frmBaika,frmNounyuuka,frmRevBaika,frmRevNounyuu)ありまして、すべてのフォームで以下のようなコードを書いています。

4つのフォームに もんこちさんが提示されたコードが記述されているのなら、
これを4つではなく、ひとつのフォームにしてしまえば良いのに・・・
というのが私の前回の投稿した内容だったのです。

そのフォームを表示するときに情報(引数)を与えることにより
若干の違いを変更するコードを記述できるということです。


それとも提示された箇所は似ているけれどそれ以外は、4つのフォームは
大きく違った処理をしているのでしょうか?

又は、行っている処理の意味がフォームを統一するには無理がある内容なのですか?


なんてことが投稿された内容からは全くわかりません。

もんこちさんのおっしゃるクラス化ですが、

まず、テキストボックスのExitイベントは、

クラスモジュールでは使用できません。
(他にも Enter、AfterUpdate、BeforeUpdateも不可)


よって、クラスモジュールにイベントを記述するならば、
ここの仕様(別のイベントで処理する例えば、Keydownイベントにするとか)
を変更しなければなりません。


それと、
>フォームによって'=選択された項目の名前・単価・単位を表示する=の部分ひっぱってく>るセル位置やセルに転記する場所が少し違うだけなので全部のシートにずらずらーっと
>書くのは無駄だなぁと思ったんです。
この違うものをはっきりと記述してください。

この辺りの情報がはっきりしたら、例題コードを考えます。

【37075】Re:同型のフォームで似たような処理・・...
質問  もんこち  - 06/4/20(木) 20:28 -

引用なし
パスワード
   ▼ichinose さん:
こんばんわ。
うまく説明ができなくて申し訳ありません

4つのフォームでコードが変わる部分ですが、

「オートフィルタを使ってリストへ候補表示」の部分では、オートフィルタをかける対象のシート
「'選択された医薬品の単価をTB2へ(小数点第2位を四捨五入)」では横方向にoffsetする数

の2点が異なるのでフォームが4つと4種類のコードをそれぞれ記述しています・・・。
フォームの形状、コントロール数は全く同じです。


  レスありがとうございます。

フォームが4つ(frmBaika,frmNounyuuka,frmRevBaika,frmRevNounyuu)ありまして、すべてのフォームで以下のようなコードを書いています。

'==========================================================================
'=オートフィルタを使ってリストへ候補表示=======================================
Private Sub TextBox1_Exit(ByVal Cancel As MSForms.ReturnBoolean)


Application.ScreenUpdating = False
 
 
  '=オブジェクト変数のセット=
  Set wbOwn = ThisWorkbook
  Set wsDrugMaster = wbOwn.Worksheets("商品マスター")
  Set wsSlip = wbOwn.Worksheets("伝票")
 
 
  '=検索キーが空白の時は何もしない=
  If TextBox1 = "" Then
   
   Exit Sub
  
  End If
  
  
  '=検索キーでオートフィルターを実行し結果をリストボックスに表示する=
  wsDrugMaster.Activate
  
  strDrugName = TextBox1.Value
  
  wsDrugMaster.Cells(1, "A").AutoFilter
  
  wsDrugMaster.Columns("HD:HD").Clear
  
  wsDrugMaster.Cells(1, "A").AutoFilter Field:=1, Criteria1:="=" & strDrugName & "*"
  
  wsDrugMaster.Range(wsDrugMaster.Cells(2, "B"), wsDrugMaster.Cells(2, "B").End(xlDown)).Copy
  
  wsDrugMaster.Cells(2, "HD").PasteSpecial
  
  ListBox1.List = wsDrugMaster.Range(wsDrugMaster.Cells(2, "HD"), _
  wsDrugMaster.Cells(2, "HD").End(xlDown)).Value
  
  Application.CutCopyMode = False
  
  
  '="伝票"シートに戻る=
  wsSlip.Select
  
  Range("A1").Select
  
  
  '=リストボックスの最初の項目を選択=
  ListBox1.ListIndex = 0


Application.ScreenUpdating = True


End Sub

'==============================================================================
'選択された医薬品の単価をTB2へ(小数点第2位を四捨五入)==========================
'==============================================================================
Private Sub ListBox1_Click()


  '=変数の宣言=
  Dim rgDrugPhonetic As Range  '"商品マスター"シート半角カナ列(検索範囲)
  Dim rgKana As Range
    
  
  '=オブジェクト変数のセット=
  Set rgDrugPhonetic = wsDrugMaster.Range(wsDrugMaster.Cells(2, "B"), _
    wsDrugMaster.Cells(2, "B").End(xlDown))
  Set wsSlip = wbOwn.Worksheets("伝票")
  
  
  '=項目が選択されていない場合はなにもしない=
  strDrugName = ListBox1.Value
  
  If strDrugName = "" Then
    
    Exit Sub
  
  End If
  
  
  '=選択された項目名をキーに単価・単位(購入価/薬価倍率)を取得する=
  For Each rgKana In rgDrugPhonetic
          
    If rgKana.Value = strDrugName Then
      
      wsSlip.Cells(7, "BH") = rgKana.Offset(0, 4) / rgKana.Offset(0, 2)
      
      dblCost = wsSlip.Cells(7, "BI").Value
      
      strUnit = rgKana.Offset(0, 3)
      
      '=選択された項目の名前・単価・単位を表示する=
      Label12.Caption = strDrugName         
      
      Label9.Caption = strUnit
      
      TextBox2.Value = Format(dblCost, "#,##0.00")
        
    End If
  
  Next rgKana
    

End Sub


【37083】Re:同型のフォームで似たような処理・・...
発言  ichinose  - 06/4/20(木) 22:55 -

引用なし
パスワード
   ▼もんこち さん:
こんばんは。


>4つのフォームでコードが変わる部分ですが、
>
>「オートフィルタを使ってリストへ候補表示」の部分では、オートフィルタをかける対象のシート

ということは、

>  Set wsDrugMaster = wbOwn.Worksheets("商品マスター")

このシート名の箇所ですね?


>「'選択された医薬品の単価をTB2へ(小数点第2位を四捨五入)」では横方向にoffsetする数

これは、
>    wsSlip.Cells(7, "BH") = rgKana.Offset(0, 4) / rgKana.Offset(0, 2)
      
     
>    strUnit = rgKana.Offset(0, 3)
この2行の
  rgKana.Offset(0, 4) の4
  rgKana.Offset(0, 2) の2
及び、
  rgKana.Offset(0, 3) の3

がフォームによって値が変わると言うことですね?

ということは、

フォームを表示するときに

shtnm String型 ---  作業を行うシート名

値ををセットする列識別番号として
 IndexA Long型 ----例の4の値を格納する変数
 IndexB Long型 ----例の2の値を格納する変数
 IndexC Long型 ----例の3の値を格納する変数


この情報を送ることが出来ればフォームは一つにまとめられますね?


>フォームが4つ(frmBaika,frmNounyuuka,frmRevBaika,frmRevNounyuu)ありまして、すべてのフォームで以下のようなコードを書いています。

ユーザーフォームは、frmとします(実際には、わかりやすい名前にして下さい)。


frmのモジュールには、
'=================================================================
public shtnm as string '---  作業を行うシート名
public IndexA as long '---  例の4の値を格納する変数
public IndexB as long '---  例の2の値を格納する変数
public IndexC as long '---  例の3の値を格納する変数

'=======================================
>Private Sub TextBox1_Exit(ByVal Cancel As MSForms.ReturnBoolean)
>
>
>Application.ScreenUpdating = False
> 
> 
>  '=オブジェクト変数のセット=
>  Set wbOwn = ThisWorkbook
  Set wsDrugMaster = wbOwn.Worksheets(shtnm)
>  Set wsSlip = wbOwn.Worksheets("伝票")
> 
> 
>  '=検索キーが空白の時は何もしない=
>  If TextBox1 = "" Then
>   
>   Exit Sub
>  
>  End If
>  
>  
>  '=検索キーでオートフィルターを実行し結果をリストボックスに表示する=
>  wsDrugMaster.Activate
>  
>  strDrugName = TextBox1.Value
>  
>  wsDrugMaster.Cells(1, "A").AutoFilter
>  
>  wsDrugMaster.Columns("HD:HD").Clear
>  
>  wsDrugMaster.Cells(1, "A").AutoFilter Field:=1, Criteria1:="=" & strDrugName & "*"
>  
>  wsDrugMaster.Range(wsDrugMaster.Cells(2, "B"), wsDrugMaster.Cells(2, "B").End(xlDown)).Copy
>  
>  wsDrugMaster.Cells(2, "HD").PasteSpecial
>  
>  ListBox1.List = wsDrugMaster.Range(wsDrugMaster.Cells(2, "HD"), _
>  wsDrugMaster.Cells(2, "HD").End(xlDown)).Value
>  
>  Application.CutCopyMode = False
>  
>  
>  '="伝票"シートに戻る=
>  wsSlip.Select
>  
>  Range("A1").Select
>  
>  
>  '=リストボックスの最初の項目を選択=
>  ListBox1.ListIndex = 0
>
>
>Application.ScreenUpdating = True
>
>
>End Sub
>
>'==============================================================================
>'選択された医薬品の単価をTB2へ(小数点第2位を四捨五入)==========================
>'==============================================================================
>Private Sub ListBox1_Click()
>
>
>  '=変数の宣言=
>  Dim rgDrugPhonetic As Range  '"商品マスター"シート半角カナ列(検索範囲)
>  Dim rgKana As Range
>    
>  
>  '=オブジェクト変数のセット=
>  Set rgDrugPhonetic = wsDrugMaster.Range(wsDrugMaster.Cells(2, "B"), _
>    wsDrugMaster.Cells(2, "B").End(xlDown))
>  Set wsSlip = wbOwn.Worksheets("伝票")
>  
>  
>  '=項目が選択されていない場合はなにもしない=
>  strDrugName = ListBox1.Value
>  
>  If strDrugName = "" Then
>    
>    Exit Sub
>  
>  End If
>  
>  
>  '=選択された項目名をキーに単価・単位(購入価/薬価倍率)を取得する=
>  For Each rgKana In rgDrugPhonetic
>          
>    If rgKana.Value = strDrugName Then
>      
      wsSlip.Cells(7, "BH") = _
          rgKana.Offset(0, IndexA) / rgKana.Offset(0, IndexB)
>      
>      dblCost = wsSlip.Cells(7, "BI").Value
>      
      strUnit = rgKana.Offset(0, IndexC)
>      
>      '=選択された項目の名前・単価・単位を表示する=
>      Label12.Caption = strDrugName         
>      
>      Label9.Caption = strUnit
>      
>      TextBox2.Value = Format(dblCost, "#,##0.00")
>        
>    End If
>  
>  Next rgKana
>    
>
>End Sub


とします。


このフォームを呼び出すプロシジャーでは、
例えば、
sub main()
  load frm
  with frm
    .shtnm="商品マスター"
    .IndexA=4
    .IndexB=2
    .IndexC=3
    .show
    end with
end sub

と記述すれば、

作業シート名として"商品マスター"

Offset値として、4,2,3という値で処理がなされます。

処理する内容によって、shtnmやIndexA〜IndexCの値を変更して、
表示すればよいですよね?

尚、IndexA〜IndexCに関しては規則性があるばならば、
一つで足りるかもしれません。

また、記述された箇所以外にも値が変わる箇所があった場合は
同じようにフォームのPublic変数として宣言して
表示(Showメソッド)前にデータを設定することで
処理できると思います。

試してみてください。

7757 / 13645 ツリー ←次へ | 前へ→
ページ:  ┃  記事番号:
2610219
(SS)C-BOARD v3.8 is Free