none
DataGridViewコンボボックスでの表示内容で質問があります(DisplayMemberからValueMember選択) RRS feed

  • 質問

  • Form_Load内で、明細部(DataGridView)  に下記コンボボックスを設けています。
    DataGridViewコンボボックスの表示内容は商品名、ValueMemberはItemNoです。

    DataGridViewコンボボックス追加コード:
            Dim dt_Item As New DataTable
            ds_DGV.Tables.Add("dt_Item")  'ds_DGV---dataset
            sqItem = "SELECT ItemNo, TagName FROM T_ItemStock" _
            & " Where ItemNo>0 and FLG_End=0" _
            & " order by TagName desc"  '"
            adapter.SelectCommand = New SqlClient.SqlCommand(sqItem, Con)
            adapter.SelectCommand.CommandType = CommandType.Text
            adapter.Fill(dt_Item)
          
            Dim dgv_CB_ItemName As New DataGridViewComboBoxColumn
            DataGridView1.Columns.Add(dgv_CB_ItemName)
            dgv_CB_ItemName.DataSource = dt_Item   'BindingSource
            dgv_CB_ItemName.HeaderText = "商品名"
            dgv_CB_ItemName.ValueMember = "ItemNo"
            dgv_CB_ItemName.DisplayMember = "TagName"
            dgv_CB_ItemName.Name = "CB_ItemName"
            dgv_CB_ItemName.FlatStyle = FlatStyle.Popup
          
            Me.DataGridView1.Columns("CB_ItemName").DataPropertyName = dt_ScrapDetails.Columns("ItemNo").ColumnName
       ’dt_ScrapDetails---DataGridView1のデータソースです。このコード行を削除してもしなくても、同じ症状です。


    症状:
    たとえば、「NC」という商品名は、コンボボックスで複数(数十件)表示されます。これは、ItemNoが異なるからです。
    同じ商品名でも、地金や寸法が異なると、それに応じてItemNoをつけていますので。
    表示が同じ「NC」でも異なる行のNCをコンボで選択したなら、それに応じた表示をさせたいのですが、うまくいきません。
    (ValueMemberのItemNoを使用して、Cell_Validatedで地金・寸法・商品番号を他のセルに表示させる設定です---(A))

      If Me.DataGridView1.Columns(e.ColumnIndex).Name = "CB_ItemName" Then
                    Dim ITN As Integer
                    If Not IsDBNull(Me.DataGridView1.CurrentRow.Cells("CB_ItemName").Value) Then
                        ITN = Cint(Me.DataGridView1.CurrentRow.Cells("CB_ItemName").Value)
                    Else
                        ITN = 0
                    End If
                  ここに、(A)用のコードが入ります
     End If


    ところが、どの行の「NC」を選択しても同じ表示になります。
    デバッグで、ITNを調べると、どの行の「NC」を選択しても同じItemNoになっています。
    本来は、別々のItemNoのはずです。 どこか、コードに問題があるのでしょうか?

    アクセスでは、個々の対応したItemNoを選択できています。

    なぜでしょうか?
    解決策を、教えていただけますか?

    個々の対応したItemNoが選択できれば、問題は解決します。
    複数列表示も考えたのですが、作成は大変なので避けたいのです。
    (DtaGridView以外の通常コンボボックスでの複数列表示は経験があり、作成はしていますが)。

    YKsaila

    2015年4月7日 1:12

回答

  • 「DataGridViewColumnで、DisplayMemberの値に重複した表示がある場合に、先に現れるValueMemberの値になってしまう」ということでしょうか?

    ComboBoxから直接ValueMemberの値を取り出して設定し直してみる。

    Public Class Form1
    
        Protected Overrides Sub OnLoad(e As EventArgs)
            MyBase.OnLoad(e)
    
            Try
                Dim ds_DGV As New DataSet
                Dim dt_ScrapDetails = ds_DGV.Tables.Add("dt_ScrapDetails")
                dt_ScrapDetails.Columns.Add("ItemNo", GetType(Integer))
                dt_ScrapDetails.Columns.Add("修正前", GetType(String))
                dt_ScrapDetails.Columns.Add("修正後", GetType(String))
    
                Dim dt_Item = ds_DGV.Tables.Add("dt_Item")  'ds_DGV---dataset
                dt_Item.Columns.Add("ItemNo", GetType(Integer))
                dt_Item.Columns.Add("TagName", GetType(String))
                If True Then
                    Dim row As DataRow = dt_Item.NewRow()
                    row(0) = DBNull.Value
    
                    row(1) = "ANC" 'Chr(Asc("A") + i).ToString()
                    dt_Item.Rows.Add(row)
                End If
    
                For i As Integer = 1 To 10
                    Dim row As DataRow = dt_Item.NewRow()
    
                    If (i = 0) Then
                        row(0) = DBNull.Value
                        row(1) = "NULL"
                    Else
                        row(0) = i
                        row(1) = "NC"
                    End If
    
    
                    dt_Item.Rows.Add(row)
                Next
    
                Dim dgv_CB_ItemName As New DataGridViewComboBoxColumn
                DataGridView1.Columns.Add(dgv_CB_ItemName)
                dgv_CB_ItemName.DataSource = dt_Item   'BindingSource
                dgv_CB_ItemName.HeaderText = "商品名"
                dgv_CB_ItemName.ValueMember = "ItemNo"
                dgv_CB_ItemName.DisplayMember = "TagName"
                dgv_CB_ItemName.Name = "CB_ItemName"
                dgv_CB_ItemName.FlatStyle = FlatStyle.Popup
    
                Me.DataGridView1.Columns("CB_ItemName").DataPropertyName = dt_ScrapDetails.Columns("ItemNo").ColumnName
                'dt_ScrapDetails---DataGridView1のデータソースです。このコード行を削除してもしなくても、同じ症状です。
    
                Me.DataGridView1.DataSource = dt_ScrapDetails
            Catch ex As Exception
                Debug.WriteLine(ex.Message)
            End Try
    
        End Sub
    
        Private Sub dgv_CellValidated(sender As Object, e As DataGridViewCellEventArgs) Handles DataGridView1.CellValidated
            Dim ITN As Integer = 0
    
            Dim clm As DataGridViewColumn = Me.DataGridView1.Columns(e.ColumnIndex)
            If (clm.Name = "CB_ItemName") Then
    
                Dim editor = TryCast(Me.DataGridView1.EditingControl, DataGridViewComboBoxEditingControl)
    
                If (editor IsNot Nothing) Then
                    Dim row As DataGridViewRow = Me.DataGridView1.Rows(e.RowIndex)
                    Dim cell As DataGridViewCell = row.Cells(clm.Name)
    
                    row.Cells("修正前").Value = cell.Value.ToString() '修正前の値を表示
                    row.Cells("修正後").Value = editor.SelectedValue.ToString() '修正後の値を表示
    
                    cell.Value = editor.SelectedValue
                    If Not IsDBNull(editor.SelectedValue) Then
                        ITN = CInt(editor.SelectedValue)
                    Else
                        ITN = 0
                    End If
                End If
            End If
        End Sub
    End Class


    個別に明示されていない限りgekkaがフォーラムに投稿したコードにはフォーラム使用条件に基づき「MICROSOFT LIMITED PUBLIC LICENSE」が適用されます。(かなり自由に使ってOK!)

    • 回答の候補に設定 Tak1waMVP, Moderator 2015年4月7日 4:05
    • 回答としてマーク yksaila 2015年4月8日 2:36
    • 編集済み gekkaMVP 2015年4月8日 3:40 スペルがおかしかったので修正しました editer → editor
    2015年4月7日 3:31
  • >なお、 '(' + ItemNo + ')'→'( + ItemNo )'としました。 データ型エラーになりましたので。

    あ~、すみません。ItemNoは文字列型じゃないんですね? では、以下のようにキャストしてみて下さい。

    '(' + cast(ItemNo as nvarchar(50)) + ')'

    で、イメージ的には、

    SELECT ItemNo, TagName,  '(' + cast(ItemNo as nvarchar(50)) + ')' as TagNameItemNo FROM T_ItemStock

    となり、私が先に掲載した例に従うと、

    newRow(0) = "abc"
    newRow(1) = 1
    newRow(2) = "abc1"

    が、以下になるイメージです。

    newRow(0) = TagName
    newRow(1) = ItemNo
    newRow(2) = TagNameItemNo

    (追記)
    >結局、複数列表示のコンボ作成と同じことになるような気がしていますが。

    いえ、コンボボックスの列はあくまで1つであり、複数列作成するわけではありません。


    ★良い回答には回答済みマークを付けよう! MVP - .NET  http://d.hatena.ne.jp/trapemiya/


    2015年4月9日 0:44
    モデレータ

すべての返信

  • 一番安直な方法は、SELECTするときにUI表示用の列をSQLで組み立てちゃうことだと思いますが、どうでしょうか?
    2015年4月7日 1:41
  • 最初からコードが変なのですが、それが影響しているということはないですか?

    > Dim dt_Item As New DataTable
    > ds_DGV.Tables.Add("dt_Item")  'ds_DGV---dataset

    この後のコードは詳しく見てませんが、上のコードの一行目で作った dt_Item と、二行目で ds_DGV の中に作った "dt_Item" という名前の DataTable は別物になるはずで、まず最初から変だと思うのですが。

    全体的にもう一度コードを見直してみませんか?


    #質問する際は、一番最初に、ご自分の環境(OS, .NET, Visual Studio のバージョン、DB サーバーとそのバージョンなど)に関する情報を最低書いていただけませんか? ガイドラインも出ていますので目を通していただければと思います。
     
    フォーラムのご利用方法(質問の投稿)について
    https://social.technet.microsoft.com/Forums/ja-JP/home?forum=announceja&announcementId=587d27f8-adc8-432a-905c-81375f8a05ec


    • 編集済み SurferOnWww 2015年4月7日 2:05 一部訂正
    2015年4月7日 2:03
  • 「DataGridViewColumnで、DisplayMemberの値に重複した表示がある場合に、先に現れるValueMemberの値になってしまう」ということでしょうか?

    ComboBoxから直接ValueMemberの値を取り出して設定し直してみる。

    Public Class Form1
    
        Protected Overrides Sub OnLoad(e As EventArgs)
            MyBase.OnLoad(e)
    
            Try
                Dim ds_DGV As New DataSet
                Dim dt_ScrapDetails = ds_DGV.Tables.Add("dt_ScrapDetails")
                dt_ScrapDetails.Columns.Add("ItemNo", GetType(Integer))
                dt_ScrapDetails.Columns.Add("修正前", GetType(String))
                dt_ScrapDetails.Columns.Add("修正後", GetType(String))
    
                Dim dt_Item = ds_DGV.Tables.Add("dt_Item")  'ds_DGV---dataset
                dt_Item.Columns.Add("ItemNo", GetType(Integer))
                dt_Item.Columns.Add("TagName", GetType(String))
                If True Then
                    Dim row As DataRow = dt_Item.NewRow()
                    row(0) = DBNull.Value
    
                    row(1) = "ANC" 'Chr(Asc("A") + i).ToString()
                    dt_Item.Rows.Add(row)
                End If
    
                For i As Integer = 1 To 10
                    Dim row As DataRow = dt_Item.NewRow()
    
                    If (i = 0) Then
                        row(0) = DBNull.Value
                        row(1) = "NULL"
                    Else
                        row(0) = i
                        row(1) = "NC"
                    End If
    
    
                    dt_Item.Rows.Add(row)
                Next
    
                Dim dgv_CB_ItemName As New DataGridViewComboBoxColumn
                DataGridView1.Columns.Add(dgv_CB_ItemName)
                dgv_CB_ItemName.DataSource = dt_Item   'BindingSource
                dgv_CB_ItemName.HeaderText = "商品名"
                dgv_CB_ItemName.ValueMember = "ItemNo"
                dgv_CB_ItemName.DisplayMember = "TagName"
                dgv_CB_ItemName.Name = "CB_ItemName"
                dgv_CB_ItemName.FlatStyle = FlatStyle.Popup
    
                Me.DataGridView1.Columns("CB_ItemName").DataPropertyName = dt_ScrapDetails.Columns("ItemNo").ColumnName
                'dt_ScrapDetails---DataGridView1のデータソースです。このコード行を削除してもしなくても、同じ症状です。
    
                Me.DataGridView1.DataSource = dt_ScrapDetails
            Catch ex As Exception
                Debug.WriteLine(ex.Message)
            End Try
    
        End Sub
    
        Private Sub dgv_CellValidated(sender As Object, e As DataGridViewCellEventArgs) Handles DataGridView1.CellValidated
            Dim ITN As Integer = 0
    
            Dim clm As DataGridViewColumn = Me.DataGridView1.Columns(e.ColumnIndex)
            If (clm.Name = "CB_ItemName") Then
    
                Dim editor = TryCast(Me.DataGridView1.EditingControl, DataGridViewComboBoxEditingControl)
    
                If (editor IsNot Nothing) Then
                    Dim row As DataGridViewRow = Me.DataGridView1.Rows(e.RowIndex)
                    Dim cell As DataGridViewCell = row.Cells(clm.Name)
    
                    row.Cells("修正前").Value = cell.Value.ToString() '修正前の値を表示
                    row.Cells("修正後").Value = editor.SelectedValue.ToString() '修正後の値を表示
    
                    cell.Value = editor.SelectedValue
                    If Not IsDBNull(editor.SelectedValue) Then
                        ITN = CInt(editor.SelectedValue)
                    Else
                        ITN = 0
                    End If
                End If
            End If
        End Sub
    End Class


    個別に明示されていない限りgekkaがフォーラムに投稿したコードにはフォーラム使用条件に基づき「MICROSOFT LIMITED PUBLIC LICENSE」が適用されます。(かなり自由に使ってOK!)

    • 回答の候補に設定 Tak1waMVP, Moderator 2015年4月7日 4:05
    • 回答としてマーク yksaila 2015年4月8日 2:36
    • 編集済み gekkaMVP 2015年4月8日 3:40 スペルがおかしかったので修正しました editer → editor
    2015年4月7日 3:31
  • こんにちは。

    この挙動はDataGridViewComboBoxの仕様だと思ってました。
    おそらくgekkaさんご提案の方向性で、何とか取得する方法を実装するしかないと思います。

    そもそも、利用者が混乱しますのでコンボボックスの表示名称はユニークであるべきな気もしますけどね。

    2015年4月7日 4:05
    モデレータ
  • gekka様へ

    DataGridView1.CellValidatedコードの中に、下記コードを入れました。
    成功しました! 
    同じ表示名でも、異なる行を選択すると、それに応じた正しいItemNoが選択されました。

    If Me.DataGridView1.Columns(e.ColumnIndex).Name = "CB_ItemName" AndAlso Not IsDBNull(Me.DataGridView1.CurrentRow.Cells("CB_ItemName").Value) Then
          Dim ITN As Integer = 0
          Dim editer = TryCast(Me.DataGridView1.EditingControl, DataGridViewComboBoxEditingControl)
         If (editer IsNot Nothing) Then
             Dim cell As DataGridViewCell = Me.DataGridView1.CurrentRow.Cells("CB_ItemName")
             cell.Value = editer.SelectedValue
             If Not IsDBNull(editer.SelectedValue) Then
             ITN = CInt(editer.SelectedValue)
             Else
             ITN = 0
             End If

          End If

    ---------略-------
    End If

    ”editer”が効いているようです。こういう時は、editer使用なんですね。
    ありがとうございました。 助かりました。
    これで、4,5日悩んでいました。 どうやってもうまくいかず、大変でした。

    知らないことが多く、本当に日々勉強です。

    これからも、よろしくお願いします。

    追記:上記コード中。 下記コードは不要でした!

    Dim cell As DataGridViewCell = Me.DataGridView1.CurrentRow.Cells("CB_ItemName")
             cell.Value = editer.SelectedValue

    YKsaila


    • 編集済み yksaila 2015年4月8日 3:17
    2015年4月8日 2:38
  • SuperOnWww様へ

    失礼しました、以後気をつけます。

    使用クライアントPC: Win7 Professional

    VB:VB2010 Express

    サーバー:Win Server 2003 R2 (standard edition)+ SQL2005

    以上が使用環境です。 サーバーは、別マシーンでネットワークを組んでいます。

    YKsaila

    2015年4月8日 2:43
  • コンボボックスが表示名と一致する最初の項目の値を引っ張ってくるのは仕様です。
    ただし、この仕様は、通常のComboBoxであれば、DropDownStyleプロパティをDropDownListに変更すれば回避できます。しかし、DataGridViewComboBoxColumnでは、この指定はできないようです。

    よって、編集時に表示されるコンボボックスのDropDownClosedで選択された値を取得しておいて、セルの編集が終了した時、すなわち編集用のコンボボックスが閉じた際に、その取っておいた値を使うように考えてみました。以下のコードを書いてみましたので、参考にしてみて下さい。

    Dim cb As ComboBox
    
    Private Sub dataGridView1_EditingControlShowing(ByVal sender As Object, ByVal e As DataGridViewEditingControlShowingEventArgs)
        cb = CType(e.Control,ComboBox)
        AddHandler cb.DropDownClosed, AddressOf Me.DataGridViewCombo_DropDownClosed
    End Sub
    
    Private selectedValue As Object
    
    Private Sub DataGridViewCombo_DropDownClosed(ByVal sender As Object, ByVal e As EventArgs)
        selectedValue = CType(sender,ComboBox).SelectedValue
    End Sub
    
    Private Sub dataGridView1_CellEndEdit(ByVal sender As Object, ByVal e As DataGridViewCellEventArgs)
        dataGridView1.Rows(e.RowIndex).Cells(0).Value = selectedValue.ToString
        RemoveHandler , AddressOf Me.DataGridViewCombo_DropDownClosed
    End Sub

    さて、YKsailaさんは、ご質問の中で、

    >複数列表示も考えたのですが、作成は大変なので避けたいのです。

    と書かれていますので、同一名称の表示に拘っていらっしゃらないようです。であれば、Hongliangさんが書かれている方法を私も推薦します。例えばSQLで以下のように書くだけで表示名はユニークになり、今回のような問題は発生しません。また、こう表示することによって、ユーザーにとっても項目を区別できるようになりますので、ベターだと思います。

    SELECT ItemNo, TagName + '(' + ItemNo + ')' as TagName FROM T_ItemStock

    (追記)
    見落としていましたが、gekkaさんの方法が簡単そうですね。編集時に表示されるコンボボックスをコントロールする質問が多かったので、つい癖でEditingControlShowingイベントを利用してしまいました。


    ★良い回答には回答済みマークを付けよう! MVP - .NET  http://d.hatena.ne.jp/trapemiya/


    2015年4月8日 2:46
    モデレータ
  • Tak1wa様へ

    >そもそも、利用者が混乱しますのでコンボボックスの表示名称はユニークであるべきな気もしますけどね

    そのとおりなですが、現実の使用場面では、こういうことも多いようです。

    商品数も、10数万となります(完売となり使用していないものも含めて)。

    使用中の商品数も数万前後もあり、商品名’NC’に付加番号をつけるのも、かえって面倒でわかりにくく不評となる状況もあるようです。

    つまり、仕方がないようです。

    YKsaila

    2015年4月8日 2:49
  • 使用中の商品数も数万前後もあり、商品名’NC’に付加番号をつけるのも、かえって面倒でわかりにくく不評となる状況もあるようです。

    操作者が一意に識別できないのであれば
    コンボボックスの並び順は開発者にしかわからないでしょうし、選択ミスを誘発します。
    どちらのNCでも良いならかまわないと思いますが…)

    どういうシステムかわかりませんが、商品名というキーワードが出ましたので一例を挙げるのであれば、間違った商品を購入してしまう、目的の商品ページにたどり着くのに時間がかかってしまう、など。

    今回の例であればItemNoを名称に含めるのは一例ですが、カテゴリやメーカー名、型番を付与するとか
    そもそもコンボボックスを2段階で絞り込んでいく形式にするなどユーザビリティの観点で見直すことも、時には必要だと思います。



    #工数とトレードオフなので難しいのはわかりますが…
    2015年4月8日 3:28
    モデレータ
  • 使用中の商品数も数万前後もあり、商品名’NC’に付加番号をつけるのも、かえって面倒でわかりにくく不評となる状況もあるようです。

    あ~、なるほど。ひょっとして、こういうことでしょうか?

    「DataGridViewの一覧表示において、コンボボックス部分は商品名だけ出て欲しい。付加番号が付くとカラムが長くなるし、余計な情報で見づらくなる。」

    であれば、コンボボックスで選択する時だけ「商品名+地金・寸法・商品番号」で表示し、DataGridViewは商品名だけ表示するようにしたらいかがでしょうか? 先に上げた私のコードを少し改造するだけで可能です。

    Public Class DataGridViewCombo
        Inherits Form
        
        Private dataTable As DataTable
        
        Public Sub New()
            MyBase.New
            InitializeComponent
            dataTable = New DataTable
            dataTable.Columns.Add(New DataColumn("Column1"))
            dataTable.Columns.Add(New DataColumn("Column2"))
            dataTable.Columns.Add(New DataColumn("Column3"))
            Dim newRow As DataRow = dataTable.NewRow
            newRow(0) = "abc"
            newRow(1) = 1
            newRow(2) = "abc1"
            dataTable.Rows.Add(newRow)
            newRow = dataTable.NewRow
            newRow(0) = "abc"
            newRow(1) = 2
            newRow(2) = "abc2"
            dataTable.Rows.Add(newRow)
            dataTable.AcceptChanges
            CType(Me.dataGridView1.Columns(0),DataGridViewComboBoxColumn).DataSource = dataTable
            CType(Me.dataGridView1.Columns(0),DataGridViewComboBoxColumn).DisplayMember = "Column1"
            CType(Me.dataGridView1.Columns(0),DataGridViewComboBoxColumn).ValueMember = "Column2"
        End Sub
        
        Private Sub button1_Click(ByVal sender As Object, ByVal e As EventArgs)
            For Each row As DataGridViewRow In dataGridView1.Rows
                System.Diagnostics.Debug.WriteLine(row.Cells(0).Value)
            Next
        End Sub
        
        Private cb As ComboBox
        
        Private Sub dataGridView1_EditingControlShowing(ByVal sender As Object, ByVal e As DataGridViewEditingControlShowingEventArgs)
            cb = CType(e.Control,ComboBox)
            cb.DisplayMember = "Column3"
            AddHandler cb.DropDownClosed, AddressOf Me.DataGridViewCombo_DropDownClosed
        End Sub
        
        Private selectedValue As Object
        
        Private Sub DataGridViewCombo_DropDownClosed(ByVal sender As Object, ByVal e As EventArgs)
            selectedValue = CType(sender,ComboBox).SelectedValue
            cb.DisplayMember = "Column1"
        End Sub
        
        Private Sub dataGridView1_CellEndEdit(ByVal sender As Object, ByVal e As DataGridViewCellEventArgs)
            dataGridView1.Rows(e.RowIndex).Cells(0).Value = selectedValue.ToString
            RemoveHandler , AddressOf Me.DataGridViewCombo_DropDownClosed
        End Sub
    End Class
    (追記)
    上記の例では列が1つしかないので余計な判定は入れていませんが、実際にはEditingControlShowingイベントハンドラ、およびCellEndEditイベントハンドラにおいて、当該のコンボボックス列である場合にだけ処理するようにして下さい。


    ★良い回答には回答済みマークを付けよう! MVP - .NET  http://d.hatena.ne.jp/trapemiya/


    2015年4月8日 5:09
    モデレータ
  • 全て、おっしゃる通りだと思います。
    ここには、欠陥があります。 というか、改善すべきところがあります。

    仕様では下記のようになっています;
    (a)現在のコンボ(商品名)選択→ ItemNo, 地金等が他のセルに準備されており、コンボ(商品名)選択後に、これらは表示されます(Cell_Validated)

    (b)また、ItemNoのセル(textboxタイプ)が別にあり、ここにItemNoを入力するとコンボ(商品名)・地金等が表示されます。
    (地金のセルは、読み取り専用です)


    実は、ここは主に棚卸で使用する箇所です。
    帳簿上と実在庫数に差異(過不足)があったときに調整するのが目的です。それ以外には、使用しません。


    過不足数調整で;
    ①ItemNoが分かっていることがほとんどですので、それを入力。
    ②商品名(コンボ)選択時 → 重量・寸法・原単価が自動表示されます、合わせてItemNoも自動表示。

    実在庫数との突合せですから、現実にはItemNo不明の場合はあり得ません。
    ②の場合は、表示されたItemNoと実在庫のItemNoとの一致を確認してから作業します(数の過不足調整)。

    ちなみに、帳簿上にない商品が出てきた場合は、ここは使用せず、別のフォームで作業します(これは完成済み)。


    ただ、私としては、②が不満で作業中なのです。
    コンボ(商品名)選択したとき、商品名だけではやはり不足です。
    ここに、商品名だけでなく、参考資料として地金・寸法等も表示させたいのです。
    これが、最終目的です。
    つまり、NC( Pt900 )、NC( K18 ) とかです、そうすればコンボ選択がしやすくなります。

    いくつか、他の書き込みでヒントをいただいていますので、明日からこれに挑戦します。 空き時間を利用しての作業なので時間がかかります。

    結局、複数列表示のコンボ作成と同じことになるような気がしていますが。

    下記は、2015/04/09 書き込み;

    商品の属性には、地金・色等があります。
    たとえば色が違っても同じ商品名です、ただ商品番号は異なるのが普通です。

    で、上記のように考えてきたのですが、商品の属性の重要度は、ものによって異なります。

    地金の場合(例:指輪)もあれば、色の場合(例:乗用車)もあります。

    しかし、ここは在庫調整場面なので、修理預かり品の場合もあります。 この場合、個別に新しくItemNoを振ります(預かり時に)。

    商品名コンボに、追加属性を表示させるとしても、商品ごとに必要な属性は異なるのが普通です。
    こういうわけですから、属性の追加表示は現実的でない、と考えました。
    つまり、このままの方が使いやすいだろう、と思います。


    ただ、ここでの問題は勉強になりますので、解決までもう少し続けようと思います。
    (当初の私の希望は解決しましたが)

    YKsaila

    • 編集済み yksaila 2015年4月9日 0:36
    2015年4月8日 14:59
  • trapemiya様へ

    ご回答、ありがとうございます。

    SELECT ItemNo, TagName + '(' + ItemNo + ')' as TagName FROM T_ItemStock

    上記コードをやってみたのですが、うまくいきません。

    なお、 '(' + ItemNo + ')' → '( + ItemNo )' としました。 データ型エラーになりましたので。

    何か、コードが不足していますか?

    下記コードを、Cell_Validatedに入れると、表示しますが。

    Dim editer = TryCast(Me.DataGridView1.EditingControl, DataGridViewComboBoxEditingControl)

    このediter使用状態で、コンボはNC(+ ItemNo) と表示し、コンボ選択後、個々の対応するItemNoを正しく表示します。

    ただ、このコンボ表示内で、具体的なItemNoを表示させることは、可能ですか?

    それは、別記事でご教示の方法しか、ありませんか?(これは、これから挑戦しますが)。

    YKsaila

    2015年4月9日 0:20
  • >なお、 '(' + ItemNo + ')'→'( + ItemNo )'としました。 データ型エラーになりましたので。

    あ~、すみません。ItemNoは文字列型じゃないんですね? では、以下のようにキャストしてみて下さい。

    '(' + cast(ItemNo as nvarchar(50)) + ')'

    で、イメージ的には、

    SELECT ItemNo, TagName,  '(' + cast(ItemNo as nvarchar(50)) + ')' as TagNameItemNo FROM T_ItemStock

    となり、私が先に掲載した例に従うと、

    newRow(0) = "abc"
    newRow(1) = 1
    newRow(2) = "abc1"

    が、以下になるイメージです。

    newRow(0) = TagName
    newRow(1) = ItemNo
    newRow(2) = TagNameItemNo

    (追記)
    >結局、複数列表示のコンボ作成と同じことになるような気がしていますが。

    いえ、コンボボックスの列はあくまで1つであり、複数列作成するわけではありません。


    ★良い回答には回答済みマークを付けよう! MVP - .NET  http://d.hatena.ne.jp/trapemiya/


    2015年4月9日 0:44
    モデレータ
  • trapemiya様へ

    SELECT ItemNo,TagName + '(' + cast(ItemNo as nvarchar(50)) + ')' as TagNameItemNo FROM T_ItemStock

    DataGridViewコンボのDisplayMemberを、 "TagNameItemNo"

    としました。

    うまくいきました、大成功です。  SQL文の中でのcast(ItemNo as nvarchar(50)) を、新しく覚えました。

    これは、いろんな場面で役に立ちますね-- この数日いくらやってもできなかったのですが、うれしいです。

    >>結局、複数列表示のコンボ作成と同じことになるような気がしていますが。

    >いえ、コンボボックスの列はあくまで1つであり、複数列作成するわけではありません。

    あ、そういう意味で書いたのでは、ありません---単に、手間・コードの複雑さについて書いたのです。

    コンボの複数列作成は大変なので、できれば避けたかったのです。 

    この方式の方が、コンボとしては見安いし、いいような気がします(個人の好みでしょうが)。

    皆様のおかげで、いろんなことを日々吸収できています。

    ありがとうございました。 これからも、よろしくお願いします。

    YKsaila

    2015年4月10日 0:48