こんばんわ。
C#のフォームのテキストボックスに[社員番号]を入力し、社員マスタから該当社員氏名を同じフォーム内のラベルに表示するという処理を行おうとしています。
以下のコードで、
[goButton]を押したあと、社員マスタの氏名をラベルに表示する部分の記述の仕方がわかりません。
社員マスタは[syainNo]と[simei]という2列のフィールドで構成されています。
private void Form1_Load(object sender, System.EventArgs e)
{
dataSet11.Clear();
sqldataAdapter1.Fill(dataSet11, "syainM");
}
private void goButton_Click(object sender, System.EventArgs e)
{
int i; //カウンタ
//検索する値が入力されていないとき
if (textBox1.Text == "")
{
MessageBox.Show("検索する社員番号を入力してください");
return;
}
//先頭から検索
for (i = 0; i < dataSet11.Tables["syainM"].Rows.Count; i++)
{
if ( dataSet11.Tables["syainM"].Rows[i]["syainNo"].ToString() == textBox1.Text)
{
//ここでラベルに社員マスタの氏名を表示する
return;
}
}
}
どなたかわかる方よろしくお願いします。
No.6ベストアンサー
- 回答日時:
そうですね。
データセットですと更新して実際にデーターベースに書き戻す際に、自分が取ってきた時と変わってないか(誰かが書き換えた)を確かめてから書き戻す必要があります。特に、合計などのように加算されていくものは要注意です。それから、for文でまわすのは効率が悪いので、できるだけやらない方が良いです。
さて、i=0ですが、実際に示されたコードで確かめましたが、問題なく動きました。
for (i = 0; i < dataSet11.Tables["syainM"].Rows.Count; i++)
だとだめで、
for (i = 1; i < dataSet11.Tables["syainM"].Rows.Count; i++)
だと良いってことですよね?う~ん、なぜでしょう?その謎を知りたくなっちゃいました(^^;
この回答への補足
遅くなり失礼しました。
更に、補足でのお礼で失礼します。
やはり、i=0だとうまく動かないんで悩み続けていました。(半分、諦めていたとも・・・(^_^;)
No.5で教えていただいたコードを記述し実行してみたら、すんなり問題なく動作しました。
本当はもっとしっかりと押さえていかなければなりませんが、今回はこのコードを使わせていただこうと思います。
ありがとうございました。
プログラムって難しいですねぇ~。
でも、完成まで頑張ってみます。また何かの際に回答を付けていただけると幸いです。
ありがとうございます。
hppさんが実行してできたということは、僕の設計で何か問題があるのでしょうね。
もう一度、一から作り直して動かしてみます。
結果はまたご報告させていただきます。
それと、データセットを使った更新の際には、書き戻すテーブルの変化も確認しなくちゃいけないのですね。
今回の質問は最終的に作ろうとしているものの部品ですので、まだまだ問題が起きそうです(^^;)
No.5
- 回答日時:
>ところで、このように直接データにアクセスするということは、何か利点があるのでしょうか?
>データセットを使い処理する方法と比べ、どんな利点・欠点があるのか不思議に思ったもので。
データセットはデータベースからデータを取ってきて、クライアントのメモリー上にコピーしてテーブルを作っています。つまり、データベースとこの時点で切り離されています。
もし、マルチユーザー環境で、誰かが社員マスタのデータを変更したとしても、それはデータセットには反映されません。もっとも今回のケースは検索する直前でデータセットを作っているので、そういった可能性は少ないですが。
また、データが巨大になればそのデータを全てとってこなくてはならなくなり、処理時間の増大につながります。当然、巨大になればforでまわせば検索時間もかかります。
では、なぜデータセットがあるかといえば、インターネットなどのセッションを継続できない場合や、そうではなくても都合が良い場合があるからです。このあたりはいろいろと解説されていると思います。
今回の場合は単純な検索ですので、わざわざローカルにデータをコピーしてデータセットを作り、そこから検索するより、直接データベースに検索させて結果だけを受け取った方がスマートでしょう。
どうしてもデータセットということになれば、せめてfor文はやめて、selectを使った方がパフォーマンスが良いように思えます。
System.Data.DataRow [] dtrows = dataSet1.Tables["syainM"].Select("syainNo=" + textBox1.Text);
if (dtrows.Length > 0)
label1.Text = dtrows[0]["simei"].ToString();
else
label1.Text = "(該当なし)";
i=0からだとうまくいかないのは不思議ですね。よろしければコードを載せてください。
こんばんわ。
再び回答ありがとうございます。
接続のタイミングの問題なのですね。
データセットの場合、接続を維持しないというのは読んでいたので、常に使っていました。
データベースに接続する回数を増やすことが、どのような状況を生み出すか少々不安に思っていました。(同時接続の際に、ロック等起こらないのか)
データベースの知識も欠如しているせいですね。(^^;)
for文だと、1レコードずつということで時間がかかるのですよね?
select文だと時間が軽減されるのですね。
コードの方も試してみます。
うまくいかないコードは、質問文の
「//ここでラベルに社員マスタの氏名を表示する」のあとに、gimmickさんに教えていただいた「label1.Text = dataSet11.Tables["syainM"].Rows[i]["simei"].ToString(); 」とし、
for文のiの初期値を1としています。
何かお気づきの点がありましたら、よろしくお願いします。
No.4
- 回答日時:
すみません。
hppです。以下の方がスマートですね。sqlConnection1.Open();
sqlCommand1.CommandText = "select simei from syainM where syainNo=" + textBox1.Text;
object kekka = sqlCommand1.ExecuteScalar();
if (kekka != null)
label1.Text = kekka.ToString();
else
label1.Text = "(該当なし)";
sqlConnection1.Close();
※sqlConnection1のConnectionString、およびsqlCommand1のconnectionにsqlConnection1がプロパティで設定してあるものとします。
※コードを見やすくするため、頭の半角は全角に変えてあります。本当はtabだけど。
回答ありがとうございます。
2つ回答していただきましたが、お礼はこちらにまとめさせていただきます。
どこかにある落とし穴にはまっているんだとは思うのですが、
なかなか解きほぐせないでいます。
i=0の時から、処理したいです。。(^^;)
質問したコードは部品として使うもので、別個にテストしていましたが、
実際に使いたいプロジェクトに組み込んでみたら、
今度は別の問題が発生し・・・とどつぼにはまるコースっぽいです。
しばらく安眠できないな・・・
回答に載せていただいたコードを見させてもらいました。
これは、プログラムから直接アクセスするタイプの書き方ですよね?
SQLを使って処理するには、このようにやるんですね。
まだ、本を見ながらデータセット作って・・・とやっている段階ですので、
このようなスマートな書き方をできるようになるのは、まだ先の話になりそうです。
ところで、このように直接データにアクセスするということは、何か利点があるのでしょうか?
データセットを使い処理する方法と比べ、どんな利点・欠点があるのか不思議に思ったもので。
No.3
- 回答日時:
特にコードは間違っていないと思うのですが・・・。
何か他に落とし穴があると思います。それはそうとして、普通は以下のようにコーディングすると思います。
sqlConnection1.Open();
sqlCommand1.CommandText = "select simei from syainM where syainNo=" + textBox1.Text;
object kekka = sqlCommand1.ExecuteScalar();
if (kekka != null)
label1.Text = sqlCommand1.ExecuteScalar().ToString();
else
label1.Text = "(該当なし)";
sqlConnection1.Close();
※sqlConnection1のConnectionString、およびsqlCommand1のconnectionにsqlConnection1がプロパティで設定してあるものとします。
※コードを見やすくするため、頭の半角は全角に変えてあります。本当はtabだけど。
No.2
- 回答日時:
それでは、ループ部分の処理をデバッガで確認したらどうですか?
データセットに正しくデータが格納されているのか?
if文でどのような文字列を比較しているのか?
等を確認すれば解決すると思いますよ。
再び回答ありがとうございます。
ブレークポイントを設定して確認してみました。
変数iが初期値”0”のままであるためでした。
その後他の部分も確認してみましたが、
if条件式の箇所でデータセットの[syainNo]部分と比較していないようです。
textBox1.Textには、テキストボックスで入力した社員Noを保持していました。
ちなみにデータセットは、データグリッドに表示させてみましたが、中身は想定したものが入っていました。
そして、あれこれいじっているうちに、変数iを1以上にすると、希望の動作になることがわかりました。
でも、データセットの行は”0”から始まっていたはずですよね?
ということは、上で書いた「比較していないのでは?」という予想も外れていたことに・・・
こうなると更に謎が・・・
うむぅ。やはりExcelのVlookUp関数みたいに簡単にはいかないものですね。
No.1
- 回答日時:
質問のコードを見る限りでは以下のようにすればよいと思いますが…。
何を悩んでいるのかがよくわかりません。
label1.Text = dataSet11.Tables["syainM"].Rows[i]["simei"];
回答ありがとうございます。
gimmickさんの書かれているコードを動かしてみました。
そうしますと、初期状態でラベルに表示されている社員氏名から変更せずに困っていました。
[社員番号] [氏名]
1000 Aさん
1001 Bさん
フォームロード時にテキストボックスには「1000」、ラベルには「Aさん」が表示されています。
その後、テキストボックスに「1001」と入力し、Enterまたは、goButtonをクリックすると、ラベルが「Bさん」に変更される
というものを作っていて、クリック後の変化が起きない(Aさんのままである)ことに困っていました。
そこで、上記質問となったということです。
個人的には、goButtonを押すごとにテキストボックスの値と同じレコードを検索するループに入り、合致したインデックス番号を取得しなおすので、ラベルに表示されるものは変化が起きると考えて作っていたのですが・・・
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# C#テキストボックスの文字を配列にいれてその後表示する 4 2022/07/17 04:47
- Visual Basic(VBA) ユーザーフォーム「frm_基本❶」を立ち上げると新規で入力する行数を右下のNoとして表示しています。 1 2023/03/16 19:02
- C言語・C++・C# c言語の問題の説明、各所ごとに 5 2023/07/26 11:03
- Visual Basic(VBA) Changeイベントで複数セルへの貼り付けおよび値削除時に1個目のセルのみエラーになる 3 2022/12/21 09:07
- C言語・C++・C# C# DatagridviewにExcelシートを反映するとエラーが出る 2 2023/05/06 17:12
- Visual Basic(VBA) 先ほど、回答者様によって教えていただいたのですがどうしたらいいか分かりません。 ユーザーフォーム上に 2 2023/02/21 22:25
- Visual Basic(VBA) ユーザーフォームの表示を追加したい 2 2023/03/26 23:18
- Visual Basic(VBA) 検索のユーザーフォームの表示について 1 2023/03/27 23:31
- Visual Basic(VBA) VBA Userformで一部別シートに転記がしたいのですが 2 2023/05/24 13:08
- JavaScript フォームが空欄の時にフォームの外をクリックすると、エラーが出るコードを調べています。 1 2023/06/25 11:51
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
DataGrdViewに関連付けたデータ...
-
【Excel VBA】先頭の「0」飛び...
-
.NET SqlDataReader のレコー...
-
C# データ配列から画像を作成す...
-
VBSやVBAでXMLファイルを読み込...
-
GridViewを自動的にスクロール...
-
天気予報データを提供してくれ...
-
GridViewにバインドせずにデー...
-
1台のサーバへの同一セグメント...
-
コンパイルエラーSubまたは...
-
Listviewのデータを上から順番...
-
ExcelVBAを使って、値...
-
count(*)で取得した値をJAVAの...
-
データ数をカウントしたいのですが
-
i=cells(Rows.Count, 1)とi=cel...
-
VB.NETで DataRow()を利用して...
-
VBAでActiveDirectoryのユーザ...
-
Excelで指定した日付から過去の...
-
【Excel VBA】指定行以降をクリ...
-
特定のセルが空白だったら、そ...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
【Excel VBA】先頭の「0」飛び...
-
DataGrdViewに関連付けたデータ...
-
Listviewのデータを上から順番...
-
GASでスプレッドシートの一番上...
-
VBAでページ番号、ページ最終行...
-
.NET SqlDataReader のレコー...
-
GridViewにバインドせずにデー...
-
【ASP.NET MVC】一覧編集画面
-
ASP C# データベースから1行取得
-
MSFlexGridのデータ表示位置の設定
-
コンパイルエラーSubまたは...
-
C# データ配列から画像を作成す...
-
エクセルマクロ小数点桁数
-
DataGridViewで表示に制限をつ...
-
スプレッドシート 一括でQRコー...
-
GridViewを自動的にスクロール...
-
DBへの重複更新を防ぐ方法について
-
エクセルVBA、数式の入ったセル...
-
GoogleEarthのKMLファイルでラ...
-
VB DataRepeaterにて条件で表示
おすすめ情報