トップ回答者
TableAdapterとDBを繋げる方法は?

質問
-
初投稿です。宜しくお願い致します。
まったくもって初歩的なことを伺っていると思いますが、調べても分からなかったので、教えて下さい。
現在、VB2005とSQLを使って、給与計算ソフトの改修作業を行っております。
作業としてはタイムカードに残業時間1、残業時間2という2項目を加えて計算させるというものです。
状況としては、タイムカードのグリットを付け加え、DB内にもその項目を付け加えてあります。
現在、この後の作業で行き詰っております。
timecardDateSet.xsd内のtimecardとtimecardTableAdapterがあるのですが、
timecardのdateset内に列を追加し、zangyou1,zangyou2の項目を新たに作りました。
この状態でデバックしてみると、
列'zangyou1'はテーブル'timecard'に属していません。
のメッセージが表示されてしまいました。
その後、timecardTableAdapter内の項目(FillGetData, FillByDayGetDateByDay, InsertRow,
UpdateRow, UpdateWorkHours, UpdateWorkHoursRow)の6項目内にも
右クリック→構成 テーブルに読み込むデータ からzangyou1 zangyou2の項目を書き加えて
再度デバックをしてみましたが、同様の結果となってしまいました。
私は、自身のここでの作業がうまく行っていないから、この様な状態になっていると思っているのですが、
いかがなのでしょうか?
また、この作業の手順を教えて頂けないでしょうか。
私自身、業界に入って2ヶ月もたたない身なので、なんともできずに歯がゆく思っており、
社内で私一人で作業しているため、誰にも相談できずに困っております。
どなたか分かる方がいらっしゃいましたら、宜しくお願い致します。
回答
-
motitti さんからの引用
>trapemiyaさん私の方では、すでに何をおっしゃられているのか分からなくなっております・・・。すみません。
TabaleAdapterを使用しているのであれば、通常、以下のようなオブジェクトが作成されているはずです。(データセットの名前は想像で書いています)
1.データセット timecardDataSet
2.データテーブル timecard
3.テーブルアダプター timecardTableAdapterこれらは型付きであるため、つまり一般的なDataSet型、DataTable型、TableAdapter型ではなく、特化したメンバーを持っています。したがって、
timeCardTbl.Rows(nowRow - 1).Item("zangyou1")
ではなく、
Me.timecardDataSet.timecard.zangyou1Columnのように、timecard型のメンバーとしてカラムにアクセスすることができるということになります。
よって、もし、timeCardTblが型付きであれば、
Me.timecardDataSet.timeCardTbl.zangyou1Columnのように書けるはずです。このようなメンバーがあるか、インテリセンス(「.」を入力した時に表示される候補)ででも調べてみて下さい。元々の私の疑問は、TableAdapterを使用されているにもかかわらず、
timeCardTbl.Rows(nowRow - 1).Item("zangyou1")
と書かれていることです。
timeCardTblはどのように作成されているのでしょうか? つもり、どのようにデータベースから値を持ってこられているのでしょうか? -
timeCardTbl(0). と入力するとインテリセンスで候補が一覧として出てきます。
この中に zangyou1 はありますでしょうか?
また、zangyou1 以外の元から入っていた項目はありますでしょうか?
zangyou1 がないのであれば私の示した手順に失敗しています。SELECT文にzangyou1やzangyou2を追加していないのではないでしょうか?
元から入っていた項目もないのであればDataTableの作成自体が間違えています。
ところで、SELECT文の構文は理解してますでしょうか?
私の示した手順が正しく行われていれば以下のようになっているはずです。
SELECT 項目1,項目2,項目3, ・・・ ,zangyou1,zangyou2 FROM timecard
-
えムナウ さんからの引用 zangyou1 がないのであれば私の示した手順に失敗しています。SELECT文にzangyou1やzangyou2を追加していないのではないでしょうか?
それはエラーの件とは別な話になるのではないでしょうか。
それに最初の方のmotittiさんの投稿で
>データのプレビュー → プレビュー で結果を見てみますと、>きちんと表示されておりました。
とありますので
列だけでなく、値も表示されているのであれば
SELECT句にも追加されているのだと思います。
また、デザイナで列を追加しただけで
(motittiさんが書かれている様に)下記の様な形式でデータにアクセスするのであれば
IntelliSenseに候補として出てくる必要もないと思います。
# SELECT句にある列は別ですがCode SnippetDim table As 型指定されたデータセットのデータテーブル
Dim rowIndex As Integer ' Rowインデックス
Dim columnName As String ' 列名
table.Rows(rowIndex).Item(columnName)table.Rows(rowIndex)(columnName)
table(rowIndex)(columnName)
-
あまり多くの人からあれこれ言われると混乱するかもしれませんが、他の方
が指摘されてない点を一言・・・(1) デザイナ画面で追加した zangyou1 と、コードの zangyou1 のスペルが違
うということはありませんか?(注1)例えば、デザイナ画面で zangyou1 を追加した時、手が滑ってスペース
バーをヒットして、zangyou1 の最後に空白が入っているというようなこ
とはないですか?デザイナ画面で zangyou1 の最後に空白文字を入れた場合、画面上では
空白は見えないので気がつきませんが、プログラムはしっかり区別して
いて、問題のコード、timeCardTbl.Rows(nowRow - 1).Item("zangyou1")
で ArgumentException がスローされ「列 'zangyou1' はテーブル
timecard に属していません。」(注2)となるはずです(ちなみに、
"zangyou1 " というように最後に空白を入れれば問題なし)。(2) テーブルが複数あって、デザイナ画面で zangyou1 を追加したのは別の
テーブル(timeCardTbl 以外のテーブル)ということはありませんか?データセットのデザイナ画面で、正しいテーブルに、正しく zangyou1 が追
加されていれば、出るはずのない問題です。チェックしてみてください。なお、型付データセット/データテーブルの場合でも、
timeCardTbl.Rows(nowRow - 1).Item("zangyou1")
で問題ないです。型付うんぬんは、はとりあえず気にしなくて良いと思いま
す(注1)全角/半角、大文字/小文字の別は問題にならないようです(実験
済み)。最初はそれが原因ではないかと思ったのですが・・・(注2)motitti さんの場合、メッセージは「列'zangyou1'はテーブル
'timecard'に属していません。」とのことですが、自分の場合と微
妙に異なる(空白がなかったり、' が余分だったり)のが気になり
ます。 -
karashima さんからの引用 えムナウ さんからの引用
また、型つきデータセットで文字列の名前でアクセスさせキャストさせる方法より table(rowIndex)(columnName)
そのままの型でアクセスする法を推奨するのも自然だと思います。 timecard(rowIndex).zangyou1
何のために型つきデータセットにしたのかわかりません。
こちらはおっしゃられている事を理解できていません。
ただ私の事をおっしゃられているのであれば、私は別に推奨はしていません。型つきデータセットの形式 timecard(rowIndex).zangyou1 これは私が推奨しているのです。
SurferOnWww
さんもおっしゃっておられますがスペルミスも可能性があると思っています。そうであればインテリセンスにはっきり出てくるはずですし、文字の打ち間違いもなくなるし、キャストも必要ありません。
すべての返信
-
>karashimaさん
zangyou1,2の項目はtimecardの欄内で右クリック → 追加 → 列
という具合で追加し、追加したコラムの名前をzangyou1,zangyou2と各々書き換えております。
また、デバックで表示されるエラーには
”ArgumentExceptionはハンドルされませんでした。”とありました。
あと、エラーが出ている(止まってしまう)部分のコードは
If Not PlusHelpWorkingHours Is Nothing Then
If timeCardTbl.Rows(nowRow - 1).Item("zangyou1").ToString <> Zangyouhours1 Then
timeCardTbl.Rows(nowRow - 1).Item("zangyou1") = zangyouhours1
End If
Else最初に来るzangyou1の所で止まってしまいます。
-
>trapemiyaさん
私の方では、すでに何をおっしゃられているのか分からなくなっております・・・。すみません。
timecardDateset.xsdは下記のような感じになっており(分かりにくくて申し訳ありません)、とりあえず、前述のように上段の
timeccardの項目から追加して言った状況です。
timecard
項目
項目
項目
zangyou1
zangyou2
timecardTableAdapter
FillGetData(・・・)
FillByDayGetDateByDay(・・・)
UpdateWorkHoursRow(・・・)
とりあえず、既存のものに見よう見真似で項目等を追加して作業していたのですが、
具体的にはどの様にしたら良いのでしょうか。
理解不足のため、色々お手数をおかけしますが、宜しくお願い致します。
-
motitti さんからの引用
>trapemiyaさん私の方では、すでに何をおっしゃられているのか分からなくなっております・・・。すみません。
TabaleAdapterを使用しているのであれば、通常、以下のようなオブジェクトが作成されているはずです。(データセットの名前は想像で書いています)
1.データセット timecardDataSet
2.データテーブル timecard
3.テーブルアダプター timecardTableAdapterこれらは型付きであるため、つまり一般的なDataSet型、DataTable型、TableAdapter型ではなく、特化したメンバーを持っています。したがって、
timeCardTbl.Rows(nowRow - 1).Item("zangyou1")
ではなく、
Me.timecardDataSet.timecard.zangyou1Columnのように、timecard型のメンバーとしてカラムにアクセスすることができるということになります。
よって、もし、timeCardTblが型付きであれば、
Me.timecardDataSet.timeCardTbl.zangyou1Columnのように書けるはずです。このようなメンバーがあるか、インテリセンス(「.」を入力した時に表示される候補)ででも調べてみて下さい。元々の私の疑問は、TableAdapterを使用されているにもかかわらず、
timeCardTbl.Rows(nowRow - 1).Item("zangyou1")
と書かれていることです。
timeCardTblはどのように作成されているのでしょうか? つもり、どのようにデータベースから値を持ってこられているのでしょうか? -
>とりあえず、既存のものに見よう見真似で項目等を追加して作業していたのですが、
>具体的にはどの様にしたら良いのでしょうか。
「アプリケーションでデータを受け取る準備」 この下の方法やチュートリアル、DataTable のデザインの下の方法やチュートリアルを理解することをお勧めします。「方法 : DataTable に列を追加する」 の一つ目の方法を使ったと思われますが、この方法は一般にテーブルにないデータをテーブルに計算列として追加するためのものです。テーブルに存在する列であれば二つ目か三つ目の方法を使います。テーブルにないデータを追加したいのでしょうか?それともテーブルに存在している列を追加したいのでしょうか?trapemiyaさん の最後の質問もこの点を聞いているんだと思います。>timeCardTbl.Rows(nowRow - 1).Item("zangyou1").ToStringこの行は一般的には以下のように書きます、もしそう書けないのであればうまくデザインできていないことになります。timeCardTbl(nowRow - 1).zangyou1.ToString() -
>trapemiyaさん
丁寧な解説ありがとうございます。
質問している私自身よく分かっていない部分が多いので、正確にお答えできている自信がないのですが、
以下のようなコードがありました。
Private Sub TimeCardGrd_AfterEdit(ByVal sender As Object, ByVal e As C1.Win.C1FlexGrid.RowColEventArgs) Handles TimeCardGrd.AfterEdit
Dim nowRow As Integer = TimeCardGrd.Selection.r1
Dim nowCol As Integer = TimeCardGrd.Selection.c1
Dim timeCardAdp As New BusinessEntity.Trn_Time_CardDataSetTableAdapters.timecardTableAdapter
Dim tenpoTimeCardAdp As New BusinessEntity.Trn_Tenpo_Time_CardDataSetTableAdapters.TRN_TENPO_TIME_CARDTableAdapterこれらは関係しているのでしょうか。
的外れなことを言っていたら、すみません。
インテリセンス(「.」を入力した時に表示される候補)…ですが、探してみます。
ありがとうございます。
-
1)DataSet の timeCardTbl の zangyou1,zangyou2 を一度削除してください。
2)以下の手順に従ってzangyou1,zangyou2 を追加してください。
「方法 : DataTable に列を追加する」の3つ目の方法。
http://msdn.microsoft.com/ja-jp/library/0c5wf85e.aspx
TableAdapter 構成ウィザードを使用して列を DataTable に追加するには
-
データセット デザイナでデータセットを開きます。詳細については、「方法 : データセット デザイナでデータセットを開く」を参照してください。
-
データ テーブルを右クリックし、[構成] をクリックします。
-
列を SELECT ステートメントに追加します。
-
[完了] をクリックします。
-
-
timeCardTbl(0). と入力するとインテリセンスで候補が一覧として出てきます。
この中に zangyou1 はありますでしょうか?
また、zangyou1 以外の元から入っていた項目はありますでしょうか?
zangyou1 がないのであれば私の示した手順に失敗しています。SELECT文にzangyou1やzangyou2を追加していないのではないでしょうか?
元から入っていた項目もないのであればDataTableの作成自体が間違えています。
ところで、SELECT文の構文は理解してますでしょうか?
私の示した手順が正しく行われていれば以下のようになっているはずです。
SELECT 項目1,項目2,項目3, ・・・ ,zangyou1,zangyou2 FROM timecard
-
えムナウ さんからの引用 zangyou1 がないのであれば私の示した手順に失敗しています。SELECT文にzangyou1やzangyou2を追加していないのではないでしょうか?
それはエラーの件とは別な話になるのではないでしょうか。
それに最初の方のmotittiさんの投稿で
>データのプレビュー → プレビュー で結果を見てみますと、>きちんと表示されておりました。
とありますので
列だけでなく、値も表示されているのであれば
SELECT句にも追加されているのだと思います。
また、デザイナで列を追加しただけで
(motittiさんが書かれている様に)下記の様な形式でデータにアクセスするのであれば
IntelliSenseに候補として出てくる必要もないと思います。
# SELECT句にある列は別ですがCode SnippetDim table As 型指定されたデータセットのデータテーブル
Dim rowIndex As Integer ' Rowインデックス
Dim columnName As String ' 列名
table.Rows(rowIndex).Item(columnName)table.Rows(rowIndex)(columnName)
table(rowIndex)(columnName)
-
table.Rows(rowIndex).Item(columnName) このアクセス方法に対して下記のエラーが出ているそうです
ArgumentExceptionはハンドルされませんでした。
列'zangyou1'はテーブル'timecard'に属していません。timecard テーブルに 列'zangyou1' がないと見るのが自然だと思います。
また、型つきデータセットで文字列の名前でアクセスさせキャストさせる方法より table(rowIndex)(columnName)
そのままの型でアクセスする法を推奨するのも自然だと思います。 timecard(rowIndex).zangyou1
何のために型つきデータセットにしたのかわかりません。 -
あまり多くの人からあれこれ言われると混乱するかもしれませんが、他の方
が指摘されてない点を一言・・・(1) デザイナ画面で追加した zangyou1 と、コードの zangyou1 のスペルが違
うということはありませんか?(注1)例えば、デザイナ画面で zangyou1 を追加した時、手が滑ってスペース
バーをヒットして、zangyou1 の最後に空白が入っているというようなこ
とはないですか?デザイナ画面で zangyou1 の最後に空白文字を入れた場合、画面上では
空白は見えないので気がつきませんが、プログラムはしっかり区別して
いて、問題のコード、timeCardTbl.Rows(nowRow - 1).Item("zangyou1")
で ArgumentException がスローされ「列 'zangyou1' はテーブル
timecard に属していません。」(注2)となるはずです(ちなみに、
"zangyou1 " というように最後に空白を入れれば問題なし)。(2) テーブルが複数あって、デザイナ画面で zangyou1 を追加したのは別の
テーブル(timeCardTbl 以外のテーブル)ということはありませんか?データセットのデザイナ画面で、正しいテーブルに、正しく zangyou1 が追
加されていれば、出るはずのない問題です。チェックしてみてください。なお、型付データセット/データテーブルの場合でも、
timeCardTbl.Rows(nowRow - 1).Item("zangyou1")
で問題ないです。型付うんぬんは、はとりあえず気にしなくて良いと思いま
す(注1)全角/半角、大文字/小文字の別は問題にならないようです(実験
済み)。最初はそれが原因ではないかと思ったのですが・・・(注2)motitti さんの場合、メッセージは「列'zangyou1'はテーブル
'timecard'に属していません。」とのことですが、自分の場合と微
妙に異なる(空白がなかったり、' が余分だったり)のが気になり
ます。 -
えムナウ さんからの引用 table.Rows(rowIndex).Item(columnName) このアクセス方法に対して下記のエラーが出ているそうです
それは承知しております。
えムナウ さんからの引用
ArgumentExceptionはハンドルされませんでした。
列'zangyou1'はテーブル'timecard'に属していません。
timecard テーブルに 列'zangyou1' がないと見るのが自然だと思います。
その通りだと思います。ですが、motittiさんが行った様にデザイナで列をを追加しただけで
データテーブルのColumns(DataColumnCollection)に列は追加されると思うのですが。
えムナウ さんからの引用
また、型つきデータセットで文字列の名前でアクセスさせキャストさせる方法より table(rowIndex)(columnName)
そのままの型でアクセスする法を推奨するのも自然だと思います。 timecard(rowIndex).zangyou1
何のために型つきデータセットにしたのかわかりません。
こちらはおっしゃられている事を理解できていません。
ただ私の事をおっしゃられているのであれば、私は別に推奨はしていません。 -
karashima さんからの引用 えムナウ さんからの引用
また、型つきデータセットで文字列の名前でアクセスさせキャストさせる方法より table(rowIndex)(columnName)
そのままの型でアクセスする法を推奨するのも自然だと思います。 timecard(rowIndex).zangyou1
何のために型つきデータセットにしたのかわかりません。
こちらはおっしゃられている事を理解できていません。
ただ私の事をおっしゃられているのであれば、私は別に推奨はしていません。型つきデータセットの形式 timecard(rowIndex).zangyou1 これは私が推奨しているのです。
SurferOnWww
さんもおっしゃっておられますがスペルミスも可能性があると思っています。そうであればインテリセンスにはっきり出てくるはずですし、文字の打ち間違いもなくなるし、キャストも必要ありません。