[[20120529194930]] 『複数のリストボックスの連携』(しろうと)  ページの最後に飛ぶ

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

 

『複数のリストボックスの連携』(しろうと)
お世話になります。出納帳をつけるのに2つのリストボックスでリストボックス1に「科目」、リストボックス2に「摘要」を表示してますが「収入・支出先(項目名)」もその連携のなかに組み込みたいのです。リストボックス1の表示された科目に応じた「摘要」か「収入・支出先」かどちらかを選択し、表示・セル入力したいのですが可能でしょうか?それとも新しくリストボックス3を作るのでしょうか?素人ですのでわかり易くご教授のほどお願います。
 今のvbaはPrivate Sub ListBox1_Change
 selIndex=Me.ListBox.ListIndex
 Select Case selListIndex
    Case 0
      Me.ListBox2.Rowsource="sheet2!b1:b3"  
     ・
  ・
  End Select
End sub

WindowsXP、Excel2003
(しろうと)  


 与えるリストを工夫すれば、リストボックスに摘要と収入・支出先(項目名)の2列を同時に表示させることは可能だけど
 残念ながら、クリック(選択)という操作で、どちらの列を選択する という、そういう概念がない。
 あくまで、その行が選択されたという認識しかできない。

 なので、2列方式でいくなら、別途、OptionButton を用意して、今から選ぶのは摘要なのか収入・支出先(項目名)なのかを
 選択してから、リストボックス2をクリックするか、または収入・支出先(項目名)専用のリストボックス3を用意するか、
 いずれかだね。

 追記)仮に2列表示したとして、その中の1行、ここに摘要と収入・支出先(項目名)が表示されるけど
  この1行に表示されている2つは、紐ついているの?
  もし、それぞれ別物なら、できる、できないということではなく、別のリストボックスにすべきだね。

 (ぶらっと)

ぶらっとさん 早速のご返事感謝します。ユーザーフォームを実行しますと一時的にリストボックス1に科目を、リストボックス2に摘要のb列を表示するようになっています。シート2ではa列科目、b〜r列までa列科目のそれぞれに応じた摘要があります。s列以降に収入・支出先の詳細がはいると思います。
 Private Sub UserForm_Activate()
   ListBox1.RowSource="sheet2!a1:a7"
   ListBox2.RowSource="sheet2!b1:b7" 現在の後にlistbox3.rowxource="sheet!s1:s7"と入るのですか?
また
 Private Sub ComandButton_Click()
   With ListBox2
     ActiveCell.Value=.List(.ListIndex,0)
     UserForm2.Hide
  End with   今のリストボックスが3つあって このコードは変わると思いますががどう変わっていくのか全く見当がつきません。 お尋ねしたい事がうまく説明できていないと思いますが。(しろうと)

 Sheet2のA列に科目、B〜R列に、その科目用の摘要、S〜AZ列に、その科目用の収入・支出先の詳細が、それぞれ左詰めで記載されているとして。
 もちろん、それぞれ1つ以上あるとして。
 また、A列の科目が2行以上であると言うことを前提にして。

 ListBox1が科目用、ListBox2が摘要用、ListBox3が収入・支出先の詳細用。

 Private Sub UserForm_Initialize()
    With Sheets("Sheet2")
        ListBox1.List = .Range("A1", .Range("A" & .Rows.Count).End(xlUp)).Value
    End With
 End Sub

 Private Sub ListBox1_Click()
    Dim z As Long
    Dim v As Variant
    With Sheets("Sheet2")
        z = WorksheetFunction.Match(ListBox1.Value, .Columns("A"), 0)
        With .Rows(z)
            v = WorksheetFunction.Transpose(.Range("B1").Resize(, WorksheetFunction.CountA(.Range("B1:R1"))).Value)
            If IsArray(v) Then
                ListBox2.List = v
            Else
                ListBox1.List = Array(v)
            End If
            v = WorksheetFunction.Transpose(.Range("S1").Resize(, WorksheetFunction.CountA(.Range("S1:AZ1"))).Value)
            If IsArray(v) Then
                ListBox3.List = v
            Else
                ListBox3.List = Array(v)
            End If
        End With
    End With
 End Sub

 (ぶらっと)

ぶらっとさん早速のご教示に有難く思います。お聞きしたいことが伝えられずご迷惑をおかけしてます。
コードをかきこみ動かしました。科目用(A列A1からA17あります)リストボックス1に表示された一番上のA1(具体的に繰越金)を選択しますと繰越金に対応した摘要はB1の1行であって、摘要用リストボックス2にB1からQ1まで出ます。C1〜Q1はミス表示となります。シート2はA列科目名のA1は繰越金があって、これに対応する摘要がB1に前年度繰越金だけがあり、この表示のみが得たいのです。具体的にA1繰越金これに対応する摘要はB1に前年度繰越金の一行、A2水道光熱費これに対応する摘要はC列でC1電気代、C2水道代、C3ガス代とC4防犯灯電気代の4行になります。
A3は負担金これに対応するD列は3行。A4は雑費に対応のE列は9行になって一番多くなります。
 またリストボックス1でA列2番目の水道光熱費を選択しますとリストボックス2にC列のC1,C2,C3,C4の4行をだしたいのですが実際にはB2からQ2までの表示となります。
リストボックス1で3つ目以降を選択しますと止ってPrivate Sub Listbox1_Click()の12行目v=worksheetfunction.transpose  で実行時エラー1004アプリケーション定義またはオブジェクト定義のエラーです。がでます。
 修正お願いできますでしょうか?
(しろうと)


 まず、エラーであったり、表示が思った通りじゃないのは、前提としているレイアウトが異なるから。
 レスの最初で、前提になるレイアウトを説明したよね。
 もちろん、これは、こちらで、決めたレイアウトなんだけど、実際のものがそれと異なっていれば
 不具合が出るのはあたりまえだよ。

 で、どうしても、そちらの現在のレイアウトでやりたい?
 運用上、あまり感心しないなぁ。
 たとえば、今は科目が 17 行だから 1行目の適用は B列、2行目の適用は C列、3行目はD列・・・
 このあたりまでは、メンテナンスも可能だと思うけど、じゃぁ科目が102個になったら、あるいは、何かの科目を廃止したら?
 さぁ、これは何列だったかなぁと指を折って勘定する?
 さらには、S列以降に科目用の収入・支出先の詳細の列があるとして、それも、ぱっと見ただけでは
 じゃぁ、Z列は、どの科目用なんだろうと。わかりにくいと思うなぁ。

 それよりも、こちらで提案したように、
 1行目が繰越金であれば、その1行目のB〜R列が繰り越し金用の適用、同じく1行目のS〜AZが繰越金用の収入・支出先の詳細 としたほうが運用しやすいと思うけど?

 もちろん、レイアウトはそちらの仕様なので、もし、それで、いくんだということなら、コードを書き直すけどね。

 ただ、夜まで外出で時間がとれないので、しばらく待ってもらうことになる。

 (ぶらっと)

ぶらっとさん ご回答ありがとう御座います。早速シート2のレイアウトを変更しました。シート2はすっきりしました。A1繰越金に対して摘要はB1の1セル、B1水道光熱費に対応した摘要はB2からF2の4セル等々 17個の科目。 収入・支出先の詳細のS列までにセルが詰まらず空白のセルがありますが問題はないでしょうか?
 実行してみますと科目用コンボボックス1で1行目の繰越金を選択しますと実行時エラーになります。
2行目の水道光熱費を選択すると動きましたが、他の科目を選択すると同じエラーになりました。
 おなじコードで止りました。
お忙しいところ申し訳ありません。
  (しろうと)


シート2のレイアウトをご指示のよう変更しました。コードは実行できました。結果、リストボックスの表示は3とうりでました。
 (1) 摘要項目が1セルの場合にはリストボックス2表示はなくリストボックス3にとび表示されますが1項目です。複数項目表示されません。
 (2) リストボックス2に全摘要項目が表示されるとリストボックス3は空白で表示はありません。
 (3) 科目16番目に『賛助区費』項目があり、摘要セルは1セルになっていますが2つのリストボックスともに表示されません。最後の17番目科目『役員報酬』はリストボックス2の表示はされませんがリストボックス3には表示はありました。
 前回のコメントはキャンセルさせてください。
  ご多忙中のところ申し訳ありませんがよろしくお願いします。
  (しろうと)

 おそまつなコードミスだった。
ListBox2 にセットすべきところで1カ所、ListBox1と記述していたところがあった。
その他、リスト配列生成のところにも、おかしなところがいくつか。
あわせて、万が一、摘要や収入・支出先の詳細が1件も登録されていないときもサポートするよう、
データの有無チェックと、その後の扱いを少し丁寧にした。

 ただ、その後にアップしてもらったコメントにつき、念のために、こちらのコードの想定を以下に。
アップしたコードは、ListBox は3つ。それぞれ、項目は1列だけ。
ListBox2は選ばれた科目に関する摘要だけ、ListBox3は選ばれた科目に対する収入・支出先の詳細だけ。
摘要は B〜R列に左詰めで、収入・支出先の詳細はS列から最終列までに、これも前詰めで。
ただし、この"S"列というのは、コード上は、

 strDtl = "S"    '詳細項目開始列記号

 ここで規定。なので、もう少し前とか後ろという要望があれば、レイアウトを変更した上で、ここを変更すればOK。

 ListBox1_Click を以下でリバイスして試してみて。

 Private Sub ListBox1_Click()
    Dim z As Long
    Dim v As Variant
    Dim x As Long
    Dim n As Long
    Dim strDtl As String

    With Sheets("Sheet2")
        strDtl = "S"    '詳細項目開始列記号
        z = WorksheetFunction.Match(ListBox1.Value, .Columns("A"), 0)
        With .Rows(z)
            x = .Range(strDtl & "1").End(xlToLeft).Column
            If x < .Columns("B").Column Then
                ListBox2.Clear
            Else
                n = x - .Columns("B").Column + 1
                v = WorksheetFunction.Transpose(.Range("B1").Resize(, n).Value)
                If IsArray(v) Then
                    ListBox2.List = v
                Else
                    ListBox2.List = Array(v)
                End If
            End If
            x = .Cells(1, .Columns.Count).End(xlToLeft).Column
            If x < .Columns(strDtl).Column Then
                ListBox3.Clear
            Else
                n = x - .Columns(strDtl).Column + 1
                v = WorksheetFunction.Transpose(.Range(strDtl & "1").Resize(, n).Value)
                If IsArray(v) Then
                    ListBox3.List = v
                Else
                    ListBox3.List = Array(v)
                End If
            End If
        End With
    End With
 End Sub

 (ぶらっと)

お忙しいなか早速ご返事感謝してます。快適に動いてます。またまたのお願いですみません。
 ワークシートの入力したいセルでクリックすれば、このユーザーフォームが作動しコンボボックス2またはコンボボックス3の任意項目を選択入力することができるコードを教授おねがいいたします。
  (しろうと)

 そういう仕様が使いやすいかどうかはなはだ疑問だけどダブルクリックで。

 シートモジュールに

 Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean)
    Cancel = True
    With UserForm1
        .Tag = Target.Address
        .Show
    End With
 End Sub

 ユーザーフォームモジュールに

 Private Sub ListBox2_Click()
    If IsObject(Evaluate(Me.Tag)) Then
        Range(Me.Tag).Value = ListBox2.Value
    End If
 End Sub

 Private Sub ListBox3_Click()
    If IsObject(Evaluate(Me.Tag)) Then
        Range(Me.Tag).Value = ListBox3.Value
    End If
 End Sub

 (ぶらっと)

お世話になります。ご指示に従い3個のコードを書き実行しますが結果は以前と変わりません。
 シートモジュールにコード書きの場合は左上隅Gneral,右上隅WorkSheet_BeforeDoubleClickと書かれていれば書き込み場所に問題はないのでしょうね?
 ご返事お待ちします。よろしく願います。
  (しろうと)


ぶらっとさん
 お世話になっています。申し訳ありませんでした。シートモジュール場が間違っていました。
 ご指示のコード書き込み実行、何の問題もなく動きました。お忙しいところ種々と教えていただき感謝します。その気持ちはことばではいいつくせません。本当に有難うございました。
 またまた前回コメント取り消しさせて頂きます。お世話になりました。
 (しろうと)

ぶらっとさん 済みませんがもう1つだけ教えて下さい。ワークシートの科目列セルでダブルクリックしてユーザーフォームを起動、科目用コンボボックス1で科目を選択すれば、そのセルに入力され続いて摘要用コンボボックス2の選択された摘要が入力された科目セルの隣接した次のセルに入力、更に収入・支出先用コンボボックス3において選択された値が、入力された摘要セルの次のセルに入力される。
 1回のユーザーフォーム起動で連続したセルに科目、摘要と収入・支出先をそれぞれ項目選択、入力はできるでしょうか?
    
      ワークシートのレイアウト  項目セル順序は次のようになっています
    
  期日 科目 摘要 収入・支出先 収入金額 支出金額 残高 

 (しろうと) 


 じゃぁ以下。(とりあえずB列が科目列というコード。違っていたら修正してね)

 シートモジュール

 Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean)
    Cancel = True
    If Target.Column <> 2 Then  'B列じゃなかったら
        MsgBox "科目列(B列)をダブルクリックしてください"
        Exit Sub
    End If
    With UserForm1
        .Tag = Target.Address
        .Show
    End With
 End Sub

 ユーザーフォームモジュール

 Private Sub ListBox1_Click()
    If IsObject(Evaluate(Me.Tag)) Then
        Range(Me.Tag).Value = ListBox1.Value
    End If
 End Sub

 Private Sub ListBox2_Click()
    If IsObject(Evaluate(Me.Tag)) Then
        Range(Me.Tag).Offset(, 1).Value = ListBox2.Value
    End If
 End Sub

 Private Sub ListBox3_Click()
    If IsObject(Evaluate(Me.Tag)) Then
        Range(Me.Tag).Offset(, 2).Value = ListBox3.Value
    End If
 End Sub

 (ぶらっと)

ぶらっとさん
 ユーザーフォームモジュールに記述するPrivate Sub LIstBox1_Click()ですが、前回記述したコードの最後End Withに続けてIfからEnd Ifまでのコードを記述しEnd Subでとじればいいのですか?
 科目列はB列です。 
 (しろうと)

 そうだった。すでに存在したんだね。
 うん、そのようにして。

 (ぶらっと)

ぶらっとさん 教授のお陰で初期目的に到達できました。マクロってとても難しいけれどこんなことまでできるとは! マクロに関心を持ちました。お陰でこれからやってみようと気持ちになりました。いろいろ教えていただき大変感謝ます。ありがとうございました。
  (しろうと)

コメント返信:

[ 一覧(最新更新順) ]


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