人に聞けない痔の悩み、これでスッキリ >>

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

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

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

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

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

A 回答 (2件)

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の単なるミスです
    • good
    • 2
この回答へのお礼

> C#だったんですね … さほど変わりないと思いますが
質問の最初に書いたんですが、わかりにくかったでしょうか。
すいません、今後質問するときはもっとわかりやすく書くよう努めます。
今回のはかなり参考になりました。ありがとうございます。

今度はforeach( DataRow dtRow in dtSource.Select("選択するための文字列"))の("選択するための文字列")で詰まってしまいました。
実際にはその位置にint型の変数を入れたかったのです。

実行すると例外が返ってきたり実行時エラーになったりで結構はまってしまいましたが("比較するカラム名 =" + 変数名)で上手くいきました。
これで何とか次の状態遷移に移れそうです。
ありがとうございました。

お礼日時:2008/10/29 15:19

ソースのDataTableのCloneメソッドでテーブル構造をコピーして


SelectメソッドでRowコレクションを取得
これを For Eachでループしてやればコピーできますよ

  dim dt as DataTable
  dim r as DataRow
  dt = dtSource.Clone
  for each rowSource DataRow in stSource.Select( "選択対象列=選択データ")
    r = dt.NewRow
    for n as integer = 0 to rowSource.ItemArray.Length - 1
      r(n) = rowSource(n)
    next
    dt.rows.add( r )
  next
といった具合でしょう

この回答への補足

せっかくソースを書いて頂いてますが、VBみたいですね。
VBでは「rowSource」や「stSource」をいった宣言外のものが使えるんでしょうか?
私はVBはわからないのですが、これはちょっと応用できそうにありません。
ありがとうございました。

補足日時:2008/10/29 09:15
    • good
    • 0

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

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

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

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

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

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

こんにちは。

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

Aベストアンサー

こんばんは.

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

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

QDataTableに特定のフィールドが存在するかどうか調べるには?

DataTableに登録されているフィールドに、特定のフィールドが存在しているかどうか調べるには、どのようにすればよいでしょうか?

dtTable.Columns.Add("TEST1")
dtTable.Columns.Add("TEST2")

dtTableにTEST1とTEST2のフィールドが登録されていたとして、

Dim tmp As String = dtTable.Rows(0).Item("TEST3"),ToString

TEST3のフィールド名で値を取得しようとすると、TEST3の列が登録されていない為、エラーとなります。

そこで、事前にTEST3というフィールドが、DataTableに存在するかどうか調べたいのです。
(ハッシュテーブルのContainsKeyメソッド等のようなものを求めています)
お分かりになる方がいましたら、宜しくお願いします。

Aベストアンサー

DataColumnCollection.Contains メソッド
http://msdn2.microsoft.com/ja-jp/library/system.data.datacolumncollection.contains(VS.80).aspx
を使用すればよいと思います。

ちなみに、DataTable.Columns が DatacolumnCollection クラスです。

Qこの行は既に別のテーブルに属しています

以下のソースで、「この行は既に別のテーブルに属しています。」というエラーが出てしまいますが、対処方法がわかりません。

どのようにしたらよろしいでしょうか?
VS2003のVBです。

    Dim Table1 As DataTable = Me.DS1.Tables("データベース1")
    Dim Table2 As DataTable = Me.DS1.Tables("データベース2")
    Dim Row1 As DataRow
    Dim Row2 As DataRow
    Row1("データ1") = 1
    Row1("データ2") = 2
    Row1("データ3") = 3
    Row2("データ1") = 2
    Row2("データ2") = 3
    Row2("データ3") = 4

    Table2.Rows.Add(Row2) ←ここでエラー
    Table1.Rows.Add(Row1)

'System.ArgumentException' のハンドルされていない例外が system.windows.forms.dll で発生しました。

追加情報 : この行は既に別のテーブルに属しています。

以下のソースで、「この行は既に別のテーブルに属しています。」というエラーが出てしまいますが、対処方法がわかりません。

どのようにしたらよろしいでしょうか?
VS2003のVBです。

    Dim Table1 As DataTable = Me.DS1.Tables("データベース1")
    Dim Table2 As DataTable = Me.DS1.Tables("データベース2")
    Dim Row1 As DataRow
    Dim Row2 As DataRow
    Row1("データ1") = 1
    Row1("データ2") = 2
    Row1("データ3") = 3
    Row2("デ...続きを読む

Aベストアンサー

お世話になります。

> Dim Row1 As DataRow
> Row1("データ1") = 1
これは、実行時に例外(NullReferenceException)が発生するはずです。

> Row1("データ1") = 1
こちらを実行する前に、
Row2 = Table1.Rows(0) とか
Row2 = Table1.NewRow とかやってると仮定して、
2 つの DataTable のレイアウトが全く同じならば
DataTable.ImportRow メソッド
を使われてはいかがでしょうか。

Dim dt As DataTable = New DataTable
dt.Columns.Add("Field1", GetType(String))
dt.Columns.Add("Field2", GetType(String))
dt.Columns.Add("Field3", GetType(String))
dt.Rows.Add(New String() {"りんご", "みかん", "ばなな"})
dt.Rows.Add(New String() {"おかし", "ごはん", "おちゃ"})

Dim copyToDt As DataTable = dt.Clone()
For Each row As DataRow In dt.Rows
  If Convert.ToString(row("Field1")) = "おかし" Then
    copyToDt.ImportRow(row)
  End If
Next

参考URL:http://msdn.microsoft.com/library/ja/default.asp?url=/library/ja/cpref/html/frlrfSystemDataDataTableClassImportRowTopic.

お世話になります。

> Dim Row1 As DataRow
> Row1("データ1") = 1
これは、実行時に例外(NullReferenceException)が発生するはずです。

> Row1("データ1") = 1
こちらを実行する前に、
Row2 = Table1.Rows(0) とか
Row2 = Table1.NewRow とかやってると仮定して、
2 つの DataTable のレイアウトが全く同じならば
DataTable.ImportRow メソッド
を使われてはいかがでしょうか。

Dim dt As DataTable = New DataTable
dt.Columns.Add("Field1", GetType(String))
dt.Columns.Add("Field2",...続きを読む

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&接続方法にし...続きを読む

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

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

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

Aベストアンサー

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

QMAX値を条件にデータを取得するには?

SQL文で困っています。
ご教授下さい。


下記のようなデータがあった場合、それぞれの区分毎に
年月が最大(最新)のデータを取得したいです。
(実際には1レコードにその他項目があり、それらも取得します。)
<検索対象データ>
区分 年月   金額
-----------------------------
A   200412  600
A   200503  560
B   200311  600
B   200508  1000
B   200504  560
C   200508  400
C   200301  1100


<取得したいデータ>

区分 年月   金額
-----------------------------
A   200503  560
B   200508  1000
C   200508  400

よろしくお願いします。

Aベストアンサー

テーブル名をXXXとすると次のようなSQLでよいと思います。(最善の方法かどうかは自信がないですが)

select B.* from (select 区分, max(年月) as 年月 from XXX group by 区分) As A
inner join XXX as B on A.区分 = B.区分 and A.年月 = B.年月
order by B.区分

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. ところが、アプリ...続きを読む

QSELECTで1件のみ取得するには?

こんにちわ。
いまORACLE9iを使用している者です。

ACCESSでは
SELECT TOP 1 項目名 FROM テーブル名
ORDER BY 項目名;
で並べ替えたデータ群のうち,先頭の1件だけを
取ることができますが,
ORACLEでそのような機能(SQL)はあるでしょうか?
教えてください。
よろしくお願いします。

Aベストアンサー

order by と rownum を併用する場合は注意が必要です。

[tbl01]
cola | colb
------------
1000 | aaaa
1001 | bbbb

というデータがある場合、
select cola from tbl01 where rownum < 1 order by cola desc;
とすると、「1001」ではなく、「1000」が返されます。
これは、order by の前に rownum < 1 が適用されてしまうからです。

解決するには、
select aaa from (select cola aaa from tbl01 order by cola desc) where rownum = 1;
とすれば良いです。

Q文字列の後ろから必要分だけ削除したい。

例1 Dim str As String = "あいうえお1234"

文字列の中の1234だけ削除したい場合は、
str = str.Remove(5,4)
という風に、5文字目の後から4文字削除にすればよいのですが、

例の"あいうえお"の部分の長さが毎回処理する度に異なる場合は、
文字列の頭から何文字目という指定ができないので、”後ろから4文字を削除したい”となります。その場合は、どのようなプロパティを使えばいいのでしょうか。

.NET環境です。

Aベストアンサー

Length(str)で文字数を取得できますので、後ろから4文字目は先頭から何文字目かは計算できると思いますが、どうでしょうか?

QVB.NET2005 DataGridViewでレコードを絞り込んで表示

Form1のTextboxより入力した数字を元にForm2のload時にoracleDBをselectしDataGridviewのテーブルの中に作成した値と一致するものを絞り込んで表示したいと考えております。
メニューのプロジェクトからDataSetを選択し、必要なDBを選択しTableadapter等も利用しています。
DBから読み込んだものをそのまま表示するだけという事は出来ました。
テキストやネットを調べながら色々試してみましたが、うまくいかず煮詰まっています。
お力を貸してください。よろしくお願いします。

Aベストアンサー

お世話になります。

TableAdapter から取ってきた DataTable を元に
DataView を使って絞り込めばよいのでは?

Dim dt As DataTable = New DataTable
dt.Columns.Add("ID", GetType(Integer))
dt.Columns.Add("FRUIT", GetType(String))

dt.Rows.Add(New Object() {1, "りんご"})
dt.Rows.Add(New Object() {2, "もも"})
dt.Rows.Add(New Object() {3, "かき"})
dt.Rows.Add(New Object() {4, "みかん"})

Dim dv As DataView = New DataView(dt)
dv.RowFilter = "FRUIT LIKE '%ん%'" '絞り込み

Me.DataGridView1.DataSource = dt '全件
Me.DataGridView2.DataSource = dv '絞り込まれた結果(りんごとみかん)

参考URL:http://www.atmarkit.co.jp/fdotnet/dotnettips/129dgfilter/dgfilter.html

お世話になります。

TableAdapter から取ってきた DataTable を元に
DataView を使って絞り込めばよいのでは?

Dim dt As DataTable = New DataTable
dt.Columns.Add("ID", GetType(Integer))
dt.Columns.Add("FRUIT", GetType(String))

dt.Rows.Add(New Object() {1, "りんご"})
dt.Rows.Add(New Object() {2, "もも"})
dt.Rows.Add(New Object() {3, "かき"})
dt.Rows.Add(New Object() {4, "みかん"})

Dim dv As DataView = New DataView(dt)
dv.RowFilter = "FRUIT LIKE '%ん%'" '絞り込み...続きを読む


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

人気Q&Aランキング