ソースとしてワークシート範囲を使用せずに複数列リストボックスのヘッダーを設定することは可能ですか?
以下は、リストボックスのリストプロパティに割り当てられたバリアントの配列を使用し、ヘッダーは空白で表示されます。
Sub testMultiColumnLb()
ReDim arr(1 To 3, 1 To 2)
arr(1, 1) = "1"
arr(1, 2) = "One"
arr(2, 1) = "2"
arr(2, 2) = "Two"
arr(3, 1) = "3"
arr(3, 2) = "Three"
With ufTestUserForm.lbTest
.Clear
.ColumnCount = 2
.List = arr
End With
ufTestUserForm.Show 1
End Sub
いいえ。リストボックスの上にヘッダーとして機能するラベルを作成します。 lisboxが変更されるたびにラベルを変更するのは大変なことだと思うかもしれません。あなたは正しいでしょう-それは苦痛です。初めて設定するのは面倒で、変更がはるかに少なくなります。しかし、私はもっと良い方法を見つけていません。
このソリューションでは、2番目のListBox要素を追加し、最初の要素の上に配置する必要があります。
このような:
次に、CreateListBoxHeader関数を呼び出して、配置を正しくし、ヘッダー項目を追加します。
結果:
Public Sub CreateListBoxHeader(body As MSForms.ListBox, header As MSForms.ListBox, arrHeaders)
' make column count match
header.ColumnCount = body.ColumnCount
header.ColumnWidths = body.ColumnWidths
' add header elements
header.Clear
header.AddItem
Dim i As Integer
For i = 0 To UBound(arrHeaders)
header.List(0, i) = arrHeaders(i)
Next i
' make it pretty
body.ZOrder (1)
header.ZOrder (0)
header.SpecialEffect = fmSpecialEffectFlat
header.BackColor = RGB(200, 200, 200)
header.Height = 10
' align header to body (should be done last!)
header.Width = body.Width
header.Left = body.Left
header.Top = body.Top - (header.Height - 1)
End Sub
Private Sub UserForm_Activate()
Call CreateListBoxHeader(Me.listBox_Body, Me.listBox_Header, Array("Header 1", "Header 2"))
End Sub
私は今この問題を見ていましたが、この解決策を見つけました。 RowSourceがセルの範囲を指す場合、複数列リストボックスの列見出しは、RowSourceのすぐ上のセルから取得されます。
ここに示した例を使用すると、リストボックス内で、単語SymbolおよびNameがタイトル見出しとして表示されます。セルAB1の単語名を変更し、フォームをVBEで再度開くと、列見出しが変更されました。
この例は、S。クリスチャンオルブライトによるVBA For Modelersのワークブックからのもので、私は彼がリストボックスに列見出しを表示する方法を理解しようとしていました:)
複数列のリストボックスの上部にヘッダーを表示する非常に簡単な解決策があります。デフォルトでfalseである「columnheads」のプロパティ値を「true」に変更するだけです。
その後、プロパティ「rowsource」でデータ範囲について言及し、データ範囲からヘッダーを除外すると、ヘッダーはデータ範囲の最初の最上行にあるはずです。そうすると、ヘッダーが自動的に選択され、ヘッダーがフリーズします。
範囲「A1:H100」のデータと最初の行である「A1:H1」にヘッダーがある場合、データ範囲は「rowsource」プロパティで言及する必要がある「A2:H100」である必要があります。 "columnheads"のperperty値はtrueである必要があります
よろしく、Asif Hameed
簡単な答え:いいえ。
私が過去に行ったことは、見出しを行0に読み込み、フォームを表示するときにListIndexを0に設定することです。これにより、「見出し」が青色で強調表示され、ヘッダーの外観が得られます。 ListIndexがゼロのままの場合、フォームアクションボタンは無視されるため、これらの値を選択することはできません。
もちろん、別のリストアイテムが選択されるとすぐに、見出しはフォーカスを失いますが、このときまでにその仕事は完了です。
このようにすることで、水平方向にスクロールする見出しを使用することもできます。これは、リストボックスの上に浮かぶ個別のラベルで行うのは困難/不可能です。逆に、リストボックスを垂直方向にスクロールする必要がある場合、見出しは表示されないままです。
基本的に、これは私がこれまで行ってきた状況で機能する妥協策です。
CboBxがワークシートから読み込まれていないComboBoxのヘッダーに次のアプローチを使用したい(たとえば、sqlからのデータ)。ワークシートからではないことを指定する理由は、RowSourceを機能させる唯一の方法は、ワークシートからロードする場合だと思うからです。
これは私にとってはうまくいきます:
アクションyourListBoxName_ClickのVBAに、次のコードを入力します。
yourComboBoxName.Activate`
yourComboBoxName.DropDown`
リストボックスをクリックすると、コンボボックスがドロップダウンして正常に機能し、リストボックス内の見出しはリストの上に残ります。
別のシートを使用せずにヘッダーを追加し、すべてをユーザーフォームにコピーするソリューションを探していました。
私の解決策は、最初の行をヘッダーとして使用してif条件を実行し、その下に項目を追加することです。
そのように:
If lborowcount = 0 Then
With lboorder
.ColumnCount = 5
.AddItem
.Column(0, lborowcount) = "Item"
.Column(1, lborowcount) = "Description"
.Column(2, lborowcount) = "Ordered"
.Column(3, lborowcount) = "Rate"
.Column(4, lborowcount) = "Amount"
End With
lborowcount = lborowcount + 1
End If
With lboorder
.ColumnCount = 5
.AddItem
.Column(0, lborowcount) = itemselected
.Column(1, lborowcount) = descriptionselected
.Column(2, lborowcount) = orderedselected
.Column(3, lborowcount) = rateselected
.Column(4, lborowcount) = amountselected
End With
lborowcount = lborowcount + 1
その例では、lboorderはリストボックスです。lborowcountは、次のリストボックス項目を追加する行をカウントします。 5列のリストボックスです。理想的ではありませんが、機能し、水平方向にスクロールする必要がある場合、「ヘッダー」は行の上に留まります。
リストボックスの上部にラベルを追加するだけでなく、変更が必要な場合、プログラムで変更する必要があるのはラベルだけです。
あなたはこれを試してみることができます。私はフォーラムに非常に新しいですが、過去にこのサイトから多くの助けを得たので、私に役立つ何かを提供したいと思いました。これは本質的に上記のバリエーションですが、私はそれがより簡単であることがわかりました。
これをユーザーフォームコードのUserform_Initializeセクションに貼り付けるだけです。ユーザーフォームにリストボックスが既にあるか、このコードの上に動的に作成されている必要があります。また、配列は見出しのリスト(「Header1」、「Header2」など)であることに注意してください。これらを独自の見出しに置き換えます。このコードは、リストボックスの列幅に基づいて上部に見出しバーを設定します申し訳ありませんが、スクロールできません-固定ラベルです。
より上級のコーダー-遠慮なくコメントまたはこれを改善してください。
Dim Mywidths As String
Dim Arrwidths, Arrheaders As Variant
Dim ColCounter, Labelleft As Long
Dim theLabel As Object
[Other code here that you would already have in the Userform_Initialize section]
Set theLabel = Me.Controls.Add("Forms.Label.1", "Test" & ColCounter, True)
With theLabel
.Left = ListBox1.Left
.Top = ListBox1.Top - 10
.Width = ListBox1.Width - 1
.Height = 10
.BackColor = RGB(200, 200, 200)
End With
Arrheaders = Array("Header1", "Header2", "Header3", "Header4")
Mywidths = Me.ListBox1.ColumnWidths
Mywidths = Replace(Mywidths, " pt", "")
Arrwidths = Split(Mywidths, ";")
Labelleft = ListBox1.Left + 18
For ColCounter = LBound(Arrwidths) To UBound(Arrwidths)
If Arrwidths(ColCounter) > 0 Then
Header = Header + 1
Set theLabel = Me.Controls.Add("Forms.Label.1", "Test" & ColCounter, True)
With theLabel
.Caption = Arrheaders(Header - 1)
.Left = Labelleft
.Width = Arrwidths(ColCounter)
.Height = 10
.Top = ListBox1.Top - 10
.BackColor = RGB(200, 200, 200)
.Font.Bold = True
End With
Labelleft = Labelleft + Arrwidths(ColCounter)
End If
Next
これが私の解決策です。
VBEのプロパティウィンドウでリストボックスの行ソースを指定すると、ヘッダーが問題なくポップアップすることに気付きました。 VBAコードを使用して行ソースを定義しようとしたときにのみ、ヘッダーが失われます。
したがって、最初に定義済みのリストボックス行ソースを、プロパティウィンドウを介してVBEの名前付き範囲として指定しました。その後、VBAコードで行ソースをリセットできます。ヘッダーは毎回表示されます。
これをlistobjectの高度なフィルターマクロと組み合わせて使用しています。これにより、rowsourceのベースとなる別の(フィルターされた)listobjectが作成されます。
これは私のために働いた
(ワークシートの)リストボックスの各列の上にラベルを自動作成する1つの方法を次に示します。
リストボックスに水平スクロールバーがない限り、(非常にきれいではありませんが)機能します。
Sub Tester()
Dim i As Long
With Me.lbTest
.Clear
.ColumnCount = 5
'must do this next step!
.ColumnWidths = "70;60;100;60;60"
.ListStyle = fmListStylePlain
Debug.Print .ColumnWidths
For i = 0 To 10
.AddItem
.List(i, 0) = "blah" & i
.List(i, 1) = "blah"
.List(i, 2) = "blah"
.List(i, 3) = "blah"
.List(i, 4) = "blah"
Next i
End With
LabelHeaders Me.lbTest, Array("Header1", "Header2", _
"Header3", "Header4", "Header5")
End Sub
Sub LabelHeaders(lb, arrHeaders)
Const LBL_HT As Long = 15
Dim T, L, shp As Shape, cw As String, arr
Dim i As Long, w
'delete any previous headers for this listbox
For i = lb.Parent.Shapes.Count To 1 Step -1
If lb.Parent.Shapes(i).Name Like lb.Name & "_*" Then
lb.Parent.Shapes(i).Delete
End If
Next i
'get an array of column widths
cw = lb.ColumnWidths
If Len(cw) = 0 Then Exit Sub
cw = Replace(cw, " pt", "")
arr = Split(cw, ";")
'start points for labels
T = lb.Top - LBL_HT
L = lb.Left
For i = LBound(arr) To UBound(arr)
w = CLng(arr(i))
If i = UBound(arr) And (L + w) < lb.Width Then w = lb.Width - L
Set shp = ActiveSheet.Shapes.AddShape(msoShapeRectangle, _
L, T, w, LBL_HT)
With shp
.Name = lb.Name & "_" & i
'do some formatting
.Line.ForeColor.RGB = vbBlack
.Line.Weight = 1
.Fill.ForeColor.RGB = RGB(220, 220, 220)
.TextFrame2.TextRange.Characters.Text = arrHeaders(i)
.TextFrame2.TextRange.Font.Size = 9
.TextFrame2.TextRange.Font.Fill.ForeColor.RGB = vbBlack
End With
L = L + w
Next i
End Sub
Lunatikの応答の別のバリエーションは、ローカルのブール値と変更イベントを使用して、初期化時に行を強調表示し、ユーザーが選択を変更した後に行を選択解除してブロックすることです。
Private Sub lbx_Change()
If Not bHighlight Then
If Me.lbx.Selected(0) Then Me.lbx.Selected(0) = False
End If
bHighlight = False
End Sub
リストボックスが初期化されたら、bHighlightとlbx.Selected(0)= Trueを設定します。これにより、選択したヘッダー行を初期化できます。その後、最初の変更により選択が解除され、行が再び選択されなくなります...