マンガでよめる痔のこと・薬のこと

VB .Netでデータベースの追加・変更をしています。
データセットのレコードを追加できたのですが、変更がわかりません。
追加は・・・dtrow = dttable.NewRowで始まり、追加したい項目を書いています。
そして終わりは・・・
''行を追加
dttable.Rows.Add(dtrow)
''データソースを更新
oleDa.Update(dttable)

変更はどうしたらよいのでしょうか?

このQ&Aに関連する最新のQ&A

A 回答 (3件)

>データセットのレコード更新がしたい



データセット?データセットにはレコードはありません
データテーブルにレコードがあります
こんな感じ
Dataset
└─DataTable
  └─DataRowCollection

新規追加ができているなら更新は簡単です

まず更新したいレコードを検索する
検索できたら、そのレコードをDataRowにて取得する

その後、対象フィールドを上書きしてからDataTableのUpdateメソッドにて更新する

[例]
Dim dRow As DataRow

'主キーにて検索(※123は検索項目値)
dRow = dTbl.Rows.Find(New Object() {123})

If Not dRow Is Nothing Then

  'フィールド更新
  dRow.Item("hogehoge") = "ほげほげ"

  dTbl.Update()

End If
    • good
    • 3

こんな感じですかね



  Dim strConn As String          '接続文字列
  Dim oleConn As OleDbConnection     'コネクション
  Dim oleDa As OleDbDataAdapter      'データアダプタ
  Dim oleCb As OleDbCommandBuilder    'コマンドビルダ
  Dim strSQL As String          'SQL
  Dim dttable As DataTable
  Dim dtrow As DataRow

  strConn = "Provider=Microsoft.Jet.OLEDB.4.0; Data Source=c:\test.mdb"
  oleConn = New OleDbConnection(strConn)

  strSQL = "SELECT * FROM " & TableName

  oleDa = New OleDbDataAdapter(strSQL, oleConn)
  oleCb = New OleDbCommandBuilder(oleDa)

  dttable = New dttable
  oleDa.Fill(dttable)
  oleDa.FillSchema(dttable)

  dtrow = dttable.NewRow

  dtrow("日付") = "20050401"

  ''行を追加
  dttable.Rows.Add(dtrow)

  ''データソースを更新
  oleDa.Update(dttable)

コマンドビルダは、データアダプタの「SelectCommand」を基にして
「InsertCommand」「UpdateCommand」「DeleteCommand」に自動でSQLを設定してくれます
まだ慣れないうちは、このコマンドビルダを使用してもよいでしょうが、
慣れてきたら個別に記述するのがよろしいでしょう

HOME > VB.NET Tips HOME > コントロール > DataSet
http://vbdotnet.fc2web.com/vbnet/control/DataSet …

この回答への補足

新規作成はできました。

更新は・・・
oleCmd.CommandText = "SELECT * FROM ファイル WHERE 日付 = '20050320';"
oleDa.SelectCommand = oleCmd
oleDa.Fill(dttable)
If dttable.Rows.Count > 0 Then
  dtrow.BeginEdit()
End if

dtrow.BeginEdit()でエラーがでます。
オブジェクト参照がオブジェクト インスタンスに設定されていません。

新規作成ではdtrow = dttable.NewRowとしているので更新の場合もdtrow = ??としなければならないと思いますが・・・何をしたら良いかわかりません。

補足日時:2005/04/01 19:21
    • good
    • 0

>Dataset


>└─DataTable
>  └─DataRowCollection

Dataset
└─DataTableCollection
  └─DataRowCollection

間違えました orz

この回答への補足

新規追加できてると思ったらできていなかったです・・・。データソースを更新する時に、
更新には、新しい行を含む DataRow コレクションが渡されたとき、有効な InsertCommand が必要です。
のエラーが出ます。

追加したい項目の書き方は・・・
dtrow = dttable.NewRow

dtrow("日付") = "20050401"

''行を追加
dttable.Rows.Add(dtrow)
''データソースを更新
oleDa.Update(dttable)

ではダメですか?
INSERT文でするのでしょうか?

補足日時:2005/04/01 14:40
    • good
    • 0

このQ&Aに関連する人気のQ&A

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

QDataTableから条件を満たした行を別のDatatableへコピーしたい

VC#2005とSQLServer2005ExpressEditionでWindowsアプリケーションを作成しています。

データベースの中から1つのマスタテーブルのデータを呼び出すのにTableAdapterを使ってDataTableにデータをバインドしました。
そこから条件を満たしている行をすべて抽出して同じ型のDataTableにデータをコピーしたいのです。

ですから、DataTableは2つ用意しています。1つは上記の通りデータをバインドしていますが、もう1つは宣言しただけなのでまだ空っぽの状態です。
DataTableにはカラムが3列あり、その中の1列をグループIDとしています。
条件としてはグループIDが同じであるということです。
やりたいことは条件を満たしている行をすべて抽出して空のデータテーブルにコピーすることです。

どなたかご存知の方いらっしゃれば教えてください。
よろしくお願いします。

Aベストアンサー

C#だったんですね … さほど変わりないと思いますが

お使いのコードが提示されていないのでこちらで適当な変数をでっち上げております
現在お使いのコードを支障の無い範囲で提示しましょう

//元のデータテーブルがdtSourceとすると
// テーブル構造をコピー
DataTable dt = dtSource.Clone();
DataRow r = null;
foreach( DataRow dtRow in dtSource.Select("選択するための文字列"))
{
  r = dt.NewRow();
  for( int n = 0; n < dtRow.ItemArray.Length; n++ )
  {
    r[n] = dtRow[n];
  }
  dt.Rows.Add( r );
}
といった具合になると思います

# 前回の投稿中のstSorceはdtSourceの単なるミスです

QDataGridViewで指定したセルの値を取得

こんにちは。

VB2008のDataGridViewで指定したセルの値を取得をする方法がわかりません。
どなたか教えてください。

Aベストアンサー

こんばんは.

 Dim Data As String
 Data = Me.DataGridView(0, 2).Value
 MsgBox(Data)

みたいな感じで取れないですかね???

QDataGridViewで変更した値を反映させたい。

VB2005、SqlServer2005環境です。

デザイナ上で、DataTableをドラッグしてやると、自動的に
バインドされたDataGridViewが出てくれるので、その方法で
DataGridViewを1つ設置しました。

このDataGridViewの表の値を変えた時、それを実際のDBのテーブルにも
反映させたいなと思ってます。
これを実現するための方法を教えていただけないでしょうか?
バインドされているので、保存できればそのまま更新されるような
イメージなのですが…その方法がわかりません。

宜しくお願いします。

Aベストアンサー

ビューからだとUpdateやDeleteなど元のテーブル対する操作は自動生成されないようです

フォームに張り付いているデータセットにクエリを追加して
テーブルを操作できるようにします
表示されているテーブルアダプタをアクティブにして データ > 追加 > Queryを実行
SQLステートメントを使用するにチェック で次へ
UPDATE で次へ
ここで クエリビルダ もしくは 直接SQLを編集し『完了』をクリック

フォームに更新用ボタンを配置
そのクリックイベントに

dim row as DataRow
for each row in DS.DaTable.Rows
  if row.RowState = DRowState.Modified then
    TableAdapter.UpdateQuery( Row("Name"), Row("ID") )
  end if
next
といった具合で更新を掛けます
# 変数名などは適宜修正してください
# DS.DaTable.Rows、TableAdapter、Row("Name"), Row("ID")などです

ビューからだとUpdateやDeleteなど元のテーブル対する操作は自動生成されないようです

フォームに張り付いているデータセットにクエリを追加して
テーブルを操作できるようにします
表示されているテーブルアダプタをアクティブにして データ > 追加 > Queryを実行
SQLステートメントを使用するにチェック で次へ
UPDATE で次へ
ここで クエリビルダ もしくは 直接SQLを編集し『完了』をクリック

フォームに更新用ボタンを配置
そのクリックイベントに

dim row as DataRow
for each row in DS.Da...続きを読む

QDataTableに入っているデータを全てinsertしたい!(C#)

はじめまして、okwebsamaです。
さっそく質問なのですが、
質問タイトルのままですが、DataTableに入っているデータを全てinsertしたいのです。
insert先のテーブルは、DataTableと同じ列名をもっています。

コード
DataTable d;
for(int i = 1; i <= d.Rows.Count; i++){
みたいな感じで作っていたんですが、ここから先が思いつきませんでした。
どなたかよろしくお願いします!!

Aベストアンサー

確認ですが、

・使っているデータベースは何ですか?
 (SQL Server or Oracle or Access or その他?)

・DBの接続方法には、何を使ってますか?
 (SqlClient? OleDb?)

・コピー元のDataSetは、型付DataSet?型無しDataSet?

・C# + ASP.NET でという話で宜しいでしょうか?
 (ASP.NETで質問されていますが、質問内容みると、C#という
 分類での質問になり、ASP.NETではないような気がします)

少々情報が足りないので、回答が的外れになるかもしれませんが、
どのDB&接続方法にしても、名前空間とクラス名が違うだけで
基本ロジック自体は、ほぼ一緒のため、
下記、型付きDataSetで、SQL Serverの例で、サンプル記載しておきます。

もし、SQL Serverじゃない&型無しDataSetの場合だったり、
どう応用したらいいかわからないという場合は、また質問して下さい。

#############################################################

// コピー元のDataTableを取得
DataTable d = コピー元DataTableを取得;

// データベースの接続
//(本来であれば、web.configやapp.configに設定されている接続先を取得する方法が望ましいわけで...)
System.Data.OleDb.OleDbConnection conn = new System.Data.OleDb.OleDbConnection("Provider=SQLOLEDB.1;Integrated Security=SSPI;Persist Security Info=False;Initial Catalog=DB名;Data Source=DBサーバのIPアドレス");

conn.Open();

// コピー元のデータ数分だけループ
foreach (DataRow row in d.Rows)
{
  // INSERT用SQLを生成
  System.Text.StringBuilder sql = new System.Text.StringBuilder();

  sql.Append("INSERT INTO [コピー先のスキーマ].[コピー先テーブル名] ");

  // INSERT項目
  System.Text.StringBuilder insertColumns = new System.Text.StringBuilder();

  // INSERT値
  System.Text.StringBuilder valueColumns = new System.Text.StringBuilder();

  // DataTableの列数分だけループ
  foreach (DataColumn col in d.Columns)
  {
    insertColumns.AppendFormat("{0},", col.ColumnName);

    // 列の型が文字列型の場合
    if (col.DataType == typeof(String))
    {
      valueColumns.AppendFormat("'{0}',", row[col.ColumnName].ToString());
    }
    else
    {
      // 列の型が文字列型以外の場合
      valueColumns.AppendFormat("{0},", row[col.ColumnName].ToString());
    }
  }

  // 不要な「,」を削除
  insertColumns.Remove(insertColumns.Length - 1, 1);
  valueColumns.Remove(valueColumns.Length - 1, 1);

  // INSERT用SQL文の生成
  sql.AppendFormat("({0}) VALUES ({1})", insertColumns.ToString(), valueColumns.ToString());

  // SQLの実行
  System.Data.OleDb.OleDbCommand command;
  command = new System.Data.OleDb.OleDbCommand(sql.ToString(), conn);
  command.ExecuteNonQuery();

  command.Dispose();
  command = null;
}

// DBの接続を閉じる
conn.Close();
conn.Dispose();
conn = null;

確認ですが、

・使っているデータベースは何ですか?
 (SQL Server or Oracle or Access or その他?)

・DBの接続方法には、何を使ってますか?
 (SqlClient? OleDb?)

・コピー元のDataSetは、型付DataSet?型無しDataSet?

・C# + ASP.NET でという話で宜しいでしょうか?
 (ASP.NETで質問されていますが、質問内容みると、C#という
 分類での質問になり、ASP.NETではないような気がします)

少々情報が足りないので、回答が的外れになるかもしれませんが、
どのDB&接続方法にし...続きを読む

QCloseとDisposeの違い

みなさまこんばんわです。よろしくお願い申し上げます。

VB.NET 2008でコーディングしています。
CloseとDisposeの違いについて教えていただきたいのです。

これらのメソッドは、開いたファイルを閉じるときなどにも使いますが、今回お尋ねするのは、フォームを閉じるとき、しかも、自ら呼び出すとき(Me.Close() と、Me.Dispose() )のみに限ったこととしてお話しさせていただきます。

たとえば、ShowDialog() で呼び出したフォームは、そのフォーム内でMe.Close() しても、プロセスは残り、たとえば、タイマーコントロールのイベントに記述していますと、それは実行され続けます。

これを防ぐために、Me.Dispose() を使います。すると、きれいにプロセスは終了し、イベントは発生しない模様です。

そこで、「フォームを閉じる」意味のMe.Close() をすべてMe.Dispose() に変えてしまいました。確実にプロセスを破棄出来ると思ったからです。Webで調べると、違いは「再利用できる、できないの違い」という答えがありましたが、それはきっと、ファイルやオブジェクトのことで、フォームの場合は、再びShowまたはShowDialogで表示させることは可能でしたので、特に問題は感じていませんでした。

ところが、アプリケーション設定で、「最後のフォームを閉じるとき」にアプリケーションがシャットダウンする設定になってるのに、シャットダウンしてくれないことが起こりました。調べてみると、Me.Dispose() が原因。Me.Close() に変えるとうまくいきました。

わけわからなくなってきました。。。

ちなみに、その残ったフォームは、スタートアップフォームであり、別のフォームからShowまたはShowDialogメソッドで呼び出したものではありません。

ここで4つの仮説を立ててみました。

1. ShowDialogで呼び出したフォームは、Me.Dispose()、Showで呼び出した、あるいは、スタートアップフォームは、Me.Close() すれば破棄できる

2. ShowDialogで呼び出したフォームは、Me.Dispose()、スタートアップフォームは、Me.Close()、Showで呼び出したフォームは、どちらでも、破棄できる

3. 呼び出し方ではなく、別の要因が存在する

4. 併記する必要がある場合がある

Me.Close()
Me.Dispose()

または、

Me.Dispose()
Me.Close()



どれが正しいのでしょうか?どなたがご存じの方がいらっしゃいましたら、ご教授いただけませんでしょうか? どうぞよろしくお願い申し上げます。ありがとうございました。

みなさまこんばんわです。よろしくお願い申し上げます。

VB.NET 2008でコーディングしています。
CloseとDisposeの違いについて教えていただきたいのです。

これらのメソッドは、開いたファイルを閉じるときなどにも使いますが、今回お尋ねするのは、フォームを閉じるとき、しかも、自ら呼び出すとき(Me.Close() と、Me.Dispose() )のみに限ったこととしてお話しさせていただきます。

たとえば、ShowDialog() で呼び出したフォームは、そのフォーム内でMe.Close() しても、プロセスは残り、たとえば、...続きを読む

Aベストアンサー

Me.Close()
Me.Dispose()
は根本的に違うものです。

formについて、Close()メソッドはフォームの表示を終了させるメソッドです。

ほかのクラスも同様。すべてのDispose()メソッドについて、これはインスタンスの破棄を明示的に行うものです。

>再利用できる、できないの違い

Dispose()はインスタンスが破棄されるため、再びコンストラクタを用いて、インスタンスを生成しないいけません。

一方Close()はインスタンスが残っているので、それを利用することができます。

>1. ところが、アプリケーション設定で、「最後のフォームを閉じるとき」にアプリケーションがシャットダウンする設定になってるのに、シャットダウンしてくれないことが起こりました。調べてみると、Me.Dispose() が原因。
Me.Close() に変えるとうまくいきました。

通常はどちらでもうまくいきます。

>2. ShowDialogで呼び出したフォームは、Me.Dispose()、スタートアップフォームは、Me.Close()、Showで呼び出したフォームは、どちらでも、破棄できる

ShowDialogの場合は、メソッド内部で、ハンドルが破棄されているため、Close()メソッドの際にDispose()メソッドが呼び出されます。

>3. 呼び出し方ではなく、別の要因が存在する

そう思います。

>4. 併記する必要がある場合がある

インスタンスを明示的に破棄したほうがよい場合は多く存在します。
Disposeが使えるメンバはIDisposableをインターフェースとして持っているメンバです。
これらのメンバは、外部とのやり取りを行うものが多くあります。
たとえばSQLClientに含まれるようなメンバです。

外部とのコネクションを確実に破棄を保障してほしいなどという場合がありますよね、このようなときに使用します。

Using構文を使用するのとまったく同じ理由になります。
正確にはUsing構文を使用できるメンバには条件があります、IDisposableをインターフェースとして持っているメンバに限るというものです。

ほかにもガーベージコレクタによるファイナライズを伴うかどうかという違いがあります。
Disposeの場合はファイナライズが同時に行われるため、使用していたメモリ空間を開放することができます。

上記のような理由により、
Me.Close()
Me.Dispose()
は両方書いたほうがよいと思います。

蛇足ですが、
Me.Dispose()
Me.Close()
はエラーになります。
Me.Dispose()により、Me本体(インスタンス)は削除されてしまいます。
存在しないMeに対してCloseメソッドを要求することはできないためです。

Me.Close()
Me.Dispose()
は根本的に違うものです。

formについて、Close()メソッドはフォームの表示を終了させるメソッドです。

ほかのクラスも同様。すべてのDispose()メソッドについて、これはインスタンスの破棄を明示的に行うものです。

>再利用できる、できないの違い

Dispose()はインスタンスが破棄されるため、再びコンストラクタを用いて、インスタンスを生成しないいけません。

一方Close()はインスタンスが残っているので、それを利用することができます。

>1. ところが、アプリ...続きを読む

QVB.NETで他のプロジェクトで作成したフォームを使う方法

こんにちは。
VB.NETのプロジェクトがぐちゃぐちゃで参照設定とかいろんなの呼んでしまっているので、新しく作成しなおしたいのですが、
新しいプロジェクトでプロジェクトを作成し、前のプロジェクトで必要なファイル(.vb、RESX)を新しいプロジェクトのフォルダにコピーしたのですが、
普通のモジュールは追加>新しい項目の追加でなんとか追加できたのですが、フォームの追加の仕方がわかりません><教えてくださいー

P.S. RESXファイルってフォームのデータが入ってるのでしょうか?そんな気がしてコピーしたのですが。

※VB6.0からVB.NETに以降した際にアップデート情報みたいなのがプログラム上にくっついてしまって.vbファイルも参照項目も増えまくってしまった

Aベストアンサー

ドラッグ&ドロップが使いやすい。
Windowsのエクスプローラでvbファイルをドラッグして、VS.NETのソリューションエクスプローラへドロップする。

Q一つのトランザクションでSELECTとUPDATEできますか? (ADO.NET)

いつもお世話になっております。

ADO.NETの話なのですが、トランザクションを開始したコネクションオブジェクトで
DataAdapterを使ったSELECTと、ExecuteNonQueryを使ったUPDATEを交互に繰り返し
行うことはできるでしょうか?

現状できていないので可能なのであれば共通関数の見直しが必要かと思っています。
いまはSELECTとUPDATEを別のコネクションで行っているのですが、UPDATE後に
同じテーブルの該当レコードをSELECTにいくため、デッドロックが発生しています。

Aベストアンサー

>それにしてもコネクションとトランザクションオブジェクトを別々に
>渡してやる必要性がよく理解できません。コネクションオブジェクトから
>トランザクションオブジェクトも参照できるのでは?と思うのですが・・・。

たしかに私も腑に落ちない・・・気がします
なにか別に設定が必要な理由があるのかも知れませんね
複数のトランザクションが存在する場合に指定が必要になるのかも!

私の過去のコードにはしっかり
sqlCommand.Transaction = tran
がありました(いつの間にか記述してたみたい)
すいません。#2ではまったくその事に触れていませんでした

憶測での回答になってしまいますが
トランザクションが割り当てられたコマンドが実行されたときに
自動的にBegin Tranされ
トランザクションが割り当てられていないコマンドが実行されたときに
自動的にCommit Tranが実行されてしまうのかも知れません
時間があったら実証して見たいと思います

Q【VB】コンボボックスにデータベースから取り出した値を入れたい

VB2005です。

表題の通りですがやり方がよくわかりません。
データベースに接続し、
SQLで重複しない値を取り出すところまではできています。

SQL=SELECT DISTINCT FieldName FROM TableName

VB6の時はこんなソースでした
Do Until rs.EOF
   Combo1.AddItem.Fields("FieldName")
   rs.MoveNext
Loop

VB2005ではどう書くのでしょう?
よろしくご教授ください。

Aベストアンサー

DataReaderを使用したサンプルです
※DBMSが記述されていないので、接続文字列はアクセスの場合です
※テキスト書きなので試験していません
※DataSetを使用する方法もありますが、コンボボックスに表示する程度ならDataReaderで大丈夫でしょう
※VB2005ならば、TableAdapterという便利なクラスがあるそうです
※VisualStudio2005 まださわってません orz

  Dim dbFilePath As String = "C:\testdb.mdb"
  Dim connectionString As String = String.Format("Provider=Microsoft.Jet.OLEDB.4.0; Data Source={0}", dbFilePath)
  Dim sql As String = "SELECT DISTINCT FieldName FROM TableName"
  Dim conn As New OleDbConnection(connectionString)
  Dim query As New OleDbCommand(sql, conn)

  Try
    conn.Open()
    Dim reader As OleDbDataReader = query.ExecuteReader()
    While (reader.Read())
      Me.ComboBox1.Items.Add(reader.Item("FieldName"))
    End While
    reader.Close()
  Catch ex As Exception
    MessageBox.Show(ex.Message)
  Finally
    conn.Close()
  End Try

DataReaderを使用したサンプルです
※DBMSが記述されていないので、接続文字列はアクセスの場合です
※テキスト書きなので試験していません
※DataSetを使用する方法もありますが、コンボボックスに表示する程度ならDataReaderで大丈夫でしょう
※VB2005ならば、TableAdapterという便利なクラスがあるそうです
※VisualStudio2005 まださわってません orz

  Dim dbFilePath As String = "C:\testdb.mdb"
  Dim connectionString As String = String.Format("Provider=Microsoft.Jet.OLEDB.4.0; Data Sourc...続きを読む

QForm間の値の渡し方

1つのForm上のコマンドボタンで別のFormを表示、そこで変数に値を入れ、そのFormを閉じ、元のFormでその変数を使いたいのですが、どうもうまくいきません。
実施したやり方は、一方のFormの宣言領域で、”Public abc As String”を宣言、両方のFormの(変数に値を入れた方と変数を使う方の)プロシージャーの宣言では引数として(abc As String)と記述しました。
因みに、両プロシージャーともイベントプロシージャーです。何か基本的なことができていないのだとは思いますが、どなたか教えていただけませんか?よろしくお願いします。

Aベストアンサー

すでに何件か回答があがっていますので、少し変わった方法をご参考までに。

あまり使われませんが、Formにはtagというプロパティがあります。
これは「文字列形式であれば何でも格納できる」という、上手く使えば便利なプロパティです。

FormAからFormBを呼び出し、FormBで変更した値をFormA.tagにセットします。
ここでFormBをUnloadしてもFormA.tagの値は影響を受けないので自由に使えます。

複数の値を呼び出し元に戻してやる場合に、区切り文字(カンマなど)で連結した文字列をtagに格納し、呼び出し元で区切り文字でsplitして、複数の値を受け渡すという手法をよく使っています。

QVB.NETのDataGridで、選択行の特定の列の内容を取得したい

タイトルにあるとおり、DataGridを使用している場合、実行時に選択された行の特定の列の内容を取得するにはどのようにすればよいのでしょうか?

DataGridは複雑で、まだよくわかっていません。
よろしくお願いします。

Aベストアンサー

選択している行番号は、dataGrid1.CurrentRowIndexでわかります。
行、列を指定して各セルにアクセスするには、
dataGrid1(行番号,列番号)でいいので
dataGrid1(dataGrid1.CurrentRowIndex,列番号)
で選択されている行の特定の列の内容を取得できます。
註:番号は、0始まり


このQ&Aを見た人がよく見るQ&A

人気Q&Aランキング