Datagridviewの値をComboboxにコピーが出来る様に変換したい

タグの編集
投稿者 社会人  (社会人) 投稿日時 2014/5/26 15:21:18
使用ソフト
・Microsoft SQL server 2008 Management Studio
・Microsoft Visual Studio 2010 Professional内のVisual Basic2010

使用PC
・XP SP3


SQLserverに置かれているデータをVB2010でDataGridViewに表示させ、データをダブルクリックすると別のフォームで作成された修正画面にダブルクリックされたデータのコピーが表示され、そこから訂正や削除などの作業を行うプログラムを作っています。

(DataGridViewがあるフォームをFmA,修正画面フォームをFmBになっています)

コピー先がTextboxとComboBoxの二種類に分かれており、ComboBoxのコピーでエラーが発生しています
エラーの原因は分かりますが、その対処方法を教えて頂きたいです。

作成中のプログラムの説明を簡単に箇条書きですが記入します。

・SQLSeverに「23,VB太郎,VB県VB市0-0-0,男性」というデータがあります(列名は左から、年齢、名前、住所、性別)

・FmAのDataGridviewに「23,VB太郎,VB県VB市,男性」と表示させて、行をダブルクリックすると年齢から性別までをコピー後にFmBの表示が同時に出来るコードを作成。

・FmBには年齢から住所までのコピーが入るTextBoxの他に不可視、不加工のTextBoxが一つだけあり、そこに一旦FmAのComboBoxの値を移してからFmBのComboBoxに反映させようとした。

・性別以外はTextBoxからTextBoxに情報をコピーするだけなので問題はありませんが、性別だけはComboBoxで表示する際にエラーが発生。

InvalidCastExceptionはハンドルされませんでした。
String "諸口                " から型 'Integer' への変換は無効です。

・原因は「男性」という文字タイプのデータをそのままComboBoxに反映されても「0、1、2」と言った数字タイプのデータでしか認識出来ない事だと思い、「男性」なら0、「女性」なら1、と変換しようとしていますが、全てELSEの反応が返ってきます。
どこを修正して、男性なら0、女性なら1を帰ってきてComboBoxに反映されるのでしょうか?

Dim AA As String = DataGridView1.CurrentRow.Cells("性別").Value.ToString
        If aa = "男性" Then
            aa = "0"
        Else
            aa = "1"
        End If



以下はエラーが発生した際のコードです。

FmAのコード
Private Sub DataGridView1_CellContentDoubleClick(sender As Object, e As System.Windows.Forms.DataGridViewCellEventArgs) Handles DataGridView1.CellContentDoubleClick

Dim B As New FmB

Dim DgA As String = DataGridView1.CurrentRow.Cells("年齢").Value.ToString
Dim DgB As String = DataGridView1.CurrentRow.Cells("名前").Value.ToString
Dim DgA As String = DataGridView1.CurrentRow.Cells("住所").Value.ToString
Dim DgB As String = DataGridView1.CurrentRow.Cells("性別").Value.ToString

B.TextBox1.Text = DgA
B.TextBox2.Text = DgB
B.TextBox3.Text = DgC
B.TextBox4.Text = DgD

B.Show()

End Sub



FmBのコード
 Private Sub fmB(sender As System.Object, e As System.EventArgs) Handles MyBase.Load

        With ComboBox1
            .Items.Add("男性")
            .Items.Add("女性")
        End With

        ComboBox1.SelectedIndex = Me.TextBox4.Text
        
 End Sub

投稿者 もちだ  (社会人) 投稿日時 2014/5/26 16:30:20
SQLSeverのことは判りませんが…全てElse側の反応になるということは、
Dim AA As String = DataGridView1.CurrentRow.Cells("性別").Value.ToString
If aa = "男性" Then
    aa = "0"
Else
    aa = "1"
End If

"男性"以外の何かが入っているという話だと思うので……まずはっきりしたいのは
・Debug.Printなどを使用して男性での値を表示した場合、男性が表示されますか?
・スペースが含まれていませんか?(DBの項目が固定長で妙に桁が多いとか)
・AAとaaは別の変数でしょうか?
(文面どおりだとAAは性別だがaaが宣言されていないので常にElseのような)
あたりでしょうか。

・ダブルコーテーションで括った数字は文字列の扱いですが、それは大丈夫でしょうか?
投稿者 (削除されました)  () 投稿日時 2014/5/26 17:46:15
(削除されました)
投稿者 (削除されました)  () 投稿日時 2014/5/26 17:46:15
(削除されました)
投稿者 社会人  (社会人) 投稿日時 2014/5/26 17:49:23
※間違いがありました。失礼しました

最初の書き込みで

Dim DgA As String = DataGridView1.CurrentRow.Cells("年齢").Value.ToString
Dim DgB As String = DataGridView1.CurrentRow.Cells("名前").Value.ToString
Dim DgA As String = DataGridView1.CurrentRow.Cells("住所").Value.ToString
Dim DgB As String = DataGridView1.CurrentRow.Cells("性別").Value.ToString


と書かれてますが

Dim DgA As String = DataGridView1.CurrentRow.Cells("年齢").Value.ToString
Dim DgB As String = DataGridView1.CurrentRow.Cells("名前").Value.ToString
Dim DgC As String = DataGridView1.CurrentRow.Cells("住所").Value.ToString
Dim DgD As String = DataGridView1.CurrentRow.Cells("性別").Value.ToString

の間違いでした。

最初の書き込みなので、削除する事が出来ないので此方に記載します


>もちださん

すみません。確かに説明不足でした。

データベースには

「23,VB太郎,VB県VB市0-0-0,男性」
「18,VB子,VB県AK市0-1-2,女性」
「56,VB爺,VB県M4市5-7-8,男性」

三つのデータを入れています。

>Debug Print

Dim DgB As String = DataGridView1.CurrentRow.Cells("性別").Value.ToString
Msgbox(DgB)


で確認すると、VB子は「女性」、それ以外の二人は「男性」と表示帰ってきました。

>スペース
スペースは入っていませんが、固定桁を短く設定し直しましたが同じ状況になっています。

>AAとaa
すみません。この掲示板に書き込む際の入力ミスです。
実際のコードは全て大文字で入力されています。

>数字は文字列の扱い
訂正して確認しましたが、結果は変わりませんでした。


何かのきっかけになればと思いますが

VB太郎→VB子→VB爺の順番で押して行くと

Dim DgD As String = DataGridView1.CurrentRow.Cells("性別").Value.ToString

MsgBox(DgD)

IF DgD = "男性" Then
   DgD = 0
Else
   DgD = 1
End IF

MsgBox(DgD)


を実行してみると

VB太郎、最初のMsgBoxで"男性",最後のMsgBoxで"1"
VB子、最初のMsgBoxで"女性",最後のMsgBoxで"1"
VB爺、最初のMsgBoxで"男性",最後のMsgBoxで"1"
と表示されました。
投稿者 通りすがりの者  (社会人) 投稿日時 2014/5/26 18:21:08
コードだけ見てもわからないのでとりあえず問題解決手法だけ。
文字列の比較で事故るときは
1.String.Compare関数などのStringクラスに実装されている比較命令で比較してみる
2.比較する元の文字列(この場合男性)もStringオブジェクトに突っ込んで、変数同士を比較してみる
3.それぞれの文字数のLengthをとってみる

まぁ、こういう問題の場合、文字列としては男性、女性、といった2文字が入っているだけのつもりなのに、取得した文字が何故かそれに改行コードとかがついてしまっていて文字数が違う、とかあるかも。
投稿者 社会人  (社会人) 投稿日時 2014/5/28 17:11:47
>もちださん
SqlServerの固定長をギリギリまで設定し直すと正常に動くようになりました!
男性、女性の項目でchar(4)にするだけで問題解決出来ました。本当に有難うございます。

>通りすがりの者
情報有難うございます。
今回は3番目の箇所が解決法でした。


無事に↓のコードで正常に動くようになりました
Dim B As New FmB

Dim DgA As String = DataGridView1.CurrentRow.Cells("年齢").Value.ToString
Dim DgB As String = DataGridView1.CurrentRow.Cells("名前").Value.ToString
Dim DgA As String = DataGridView1.CurrentRow.Cells("住所").Value.ToString
Dim DgB As String = DataGridView1.CurrentRow.Cells("性別").Value.ToString

B.TextBox1.Text = DgA
B.TextBox2.Text = DgB
B.TextBox3.Text = DgC

If DgD = "男性" Then
   B.Textbox4.text = 0
Else
   B.Textbox4.text = 1
End if

B.show


しかし、FmBの※印の箇所でエラーが発生しました

InvalidCastExceptionはハンドルされませんでした。
String "" から型 'Integer' への変換は無効です。

 Private Sub fmB(sender As System.Object, e As System.EventArgs) Handles MyBase.Load

        With ComboBox1
            .Items.Add("男性")
            .Items.Add("女性")
        End With

        ComboBox1.SelectedIndex = Me.TextBox4.Text※
        
 End Sub


String型からInteger型にデータを変更しようと色々試しましたが、変化はありませんでした。
どうすれば正常に動きますか?
下のコードは上記にあるコードに手を加えたものです

Dim RPG As Integer
Dim B As New FmB

Dim DgA As String = DataGridView1.CurrentRow.Cells("年齢").Value.ToString
Dim DgB As String = DataGridView1.CurrentRow.Cells("名前").Value.ToString
Dim DgA As String = DataGridView1.CurrentRow.Cells("住所").Value.ToString
Dim DgB As String = DataGridView1.CurrentRow.Cells("性別").Value.ToString

B.TextBox1.Text = DgA
B.TextBox2.Text = DgB
B.TextBox3.Text = DgC


If DgD = "男性" Then
   RPG = 1
   B.TextBox4.Text = RPG
Else
   RPG = 0
   B.TextBox4.Text = RPG
End If



投稿者 shu  (社会人) 投稿日時 2014/5/29 08:34:27
> >もちださん
> SqlServerの固定長をギリギリまで設定し直すと正常に動くようになりました!
> 男性、女性の項目でchar(4)にするだけで問題解決出来ました。本当に有難うございます。
データ構造を変更して対応というのは良い対応とはいえないです。
元々4でなかったのはなぜなのか、本当に4にしてしまって大丈夫なのかとか考慮しないと駄目です。
charをvarcharやnvarcharにするとかcharのままでも取得時にトリムするとかの方がよいです。
投稿者 社会人  (社会人) 投稿日時 2014/5/29 17:03:46

問題が自己解決しました。

Dim B As New FmB

Dim L As Integer
L = 0

Dim M As Integer
M = 1

Dim DgA As String = DataGridView1.CurrentRow.Cells("年齢").Value.ToString
Dim DgB As String = DataGridView1.CurrentRow.Cells("名前").Value.ToString
Dim DgA As String = DataGridView1.CurrentRow.Cells("住所").Value.ToString
Dim DgB As String = DataGridView1.CurrentRow.Cells("性別").Value.ToString

B.TextBox1.Text = DgA
B.TextBox2.Text = DgB
B.TextBox3.Text = DgC

If DgD = "男性" Then
   B.Textbox4.text = L
Else
   B.Textbox4.text = M
End if

B.show




に変更する事で、エラー回避する事が出来ました。


>shuさん
指摘有難うございます。
データ構造の件なんですが、桁数の違いでエラーが発生しないと思い込んで初期値のまま設定していました。
データ構造の変更は必須になりましたので、この件に関しては大丈夫です。
此方で調べてから、合致するデータ型に変更しよと考えていますが、二点だけ質問しても宜しいでしょうか?

・取得時のトリムが良く分かりません。説明して貰えると助かります。
・仮に、今回の性別を都道府県に置き換えた場合「北海道、大阪、鹿児島」などのデータの桁数が微妙に違い場合のデータ構造の対処方法があれば教えて欲しいです。
投稿者 shu  (社会人) 投稿日時 2014/5/29 17:49:13
> ・取得時のトリムが良く分かりません。説明して貰えると助かります。
char項目は後ろに不足数分の半角スペースが入ります。
RTrimで取得する(Select句)などして有効な文字列にトリムすると後の処理がしやすくなります。


>・仮に、今回の性別を都道府県に置き換えた場合「北海道、大阪、鹿児島」などのデータの桁数が微妙に違い場合のデータ構造の対処方法があれば教えて欲しいです。 
一番多い桁数に合わせます。
char(6)         固定長6byte
nchar(3)       固定長3文字
varchar(6)    可変長6byte
nvarchar(3)   可変長3文字
のどれでも格納は出来ます。PrimaryKeyでない場合nvarcharにしておいた方が処理が楽になります。
キー項目の場合はcharにしておいた方がインデックスが少なからず軽くなります。
投稿者 社会人  (社会人) 投稿日時 2014/6/4 16:39:12
>shuさん
返事が遅くなりましたが、詳しい説明有難うございます。
今後も、分かる範囲で宜しくお願いします。