- take
- 大ベテラン
- 会議室デビュー日: 2004/08/13
- 投稿数: 177
- お住まい・勤務地: 沖縄県北部
|
投稿日時: 2006-04-13 10:46
いつもお世話になります。SQLSERVER2000、EXCEL2000VBAです。
DBの定義をVBAで取得しようと思ってます。テーブル名、フィールド名、
NOTNULL制約等は取得できたのですが、主キーを取得しようと下のコード
を実行すると、
「オブジェクトまたはプロバイダは要求された操作を実行できません」
というエラーメッセージが出ます。
コード: |
|
Dim cn As ADODB.Connection
Dim cat As ADOX.Catalog
Dim tbl As ADOX.Table
Dim col As ADOX.Column
Dim idx As ADOX.Index
Dim Rs As ADODB.Recordset
Set cn = New ADODB.Connection
Set cat = New ADOX.Catalog
Set Rs = New ADODB.Recordset
Dim strRet As String
cn.Open DSNName
cat.ActiveConnection = cn
フィールドカウント = 0
For i = 0 To Rs.Fields.Count - 1
If cat.Tables(テーブル名).Keys(0).Columns(i).Name _
= Rs.Fields(i).Name Then
DB.キー(フィールドカウント) = "○"
End If
Next 'i-next
|
主キーの判定のところのロジックが多少おかしいのは分かりますが、
そもそもエラーメッセージからするとsqlserverでは対応してない
取り方なのかとも思っております。
cat.Tables(テーブル名).Keys(0)で情報を取ろうとするとエラーに
なるようです。
他の対応方法、もしくは修正方法をご存知の方がいらっしゃいましたら
ご教授のほどよろしくお願いします。
|
- じゃんぬねっと
- ぬし
- 会議室デビュー日: 2004/12/22
- 投稿数: 7811
- お住まい・勤務地: 愛知県名古屋市
|
投稿日時: 2006-04-13 11:07
引用: |
|
takeさんの書き込み (2006-04-13 10:46) より:
主キーの判定のところのロジックが多少おかしいのは分かりますが、
|
というよりは、なぜ Recordset が必要なのでしょうか?
コード: |
|
Private Sub MakiMakiLove()
Dim hConnection As ADODB.Connection
Set hConnection = New ADODB.Connection
hConnection.ConnectionString = "Provider=SQLOLEDB; Data Source=Server; Initial Catalog=NorthWind; Integrated Security=SSPI;"
On Error GoTo CatchOpenException
Call hConnection.Open
On Error GoTo FinallyDispose
Dim hCatalog As ADOX.Catalog
Set hCatalog = New ADOX.Catalog
hCatalog.ActiveConnection = hConnection
Dim i As Integer
For i = 0 To hCatalog.Tables("Orders").Keys.Count - 1
Call MsgBox(hCatalog.Tables("Orders").Keys(i).Name)
Next i
FinallyDispose:
If Not hConnection Is Nothing Then
If hConnection.State <> adStateClosed Then
Call hConnection.Close
End If
End If
Exit Sub
CatchOpenException:
Call MsgBox("データベース接続が確立できませんですた")
End Sub
|
こんな感じで良いのではないでしょうか? (試していませんが)
_________________ C# と VB.NET の入門サイト
じゃんぬねっと日誌
|
- take
- 大ベテラン
- 会議室デビュー日: 2004/08/13
- 投稿数: 177
- お住まい・勤務地: 沖縄県北部
|
投稿日時: 2006-04-13 11:48
じゃんぬさん、ご返答ありがとうございます。
引用: |
|
じゃんぬねっとさんの書き込み (2006-04-13 11:07) より:
なぜ Recordset が必要なのでしょうか?
|
すみません、消し忘れです。後続の処理で使用するもので・・・(汗)
プロバイダを変更してSQLOLEDBにするとkeysプロパティが使える
ようになったみたいです。
ただ、主キーがどのフィールドに対応してるのかを取得したい時に
どのようにしたらいいのかが分かりません。主キーの数を数えようと
して下のようにしてみると前回と同じくプロバイダエラーになってしまい
ます。
Debug.Print cat.Tables("T_New").Keys(0).Columns.Count
というよりもまず、ADOXについて根本的に分かってないので調べ方等も
教えていただけると回答していただく方の時間を無駄にしなくていいような
気もします。
皆様はどのようにして調べていらっしゃるのでしょうか?
また、主キーに対応するフィールドの取得はどのようにしたらいいのでしょう?
すみませんが、引き続きよろしくお願いします。
|
- じゃんぬねっと
- ぬし
- 会議室デビュー日: 2004/12/22
- 投稿数: 7811
- お住まい・勤務地: 愛知県名古屋市
|
投稿日時: 2006-04-13 13:13
引用: |
|
takeさんの書き込み (2006-04-13 11:48) より:
また、主キーに対応するフィールドの取得はどのようにしたらいいのでしょう?
すみませんが、引き続きよろしくお願いします。
|
失礼しました、フィールド名の取得だったのですね。
多分こうだと思います。(先ほど同様、試していません)
コード: |
|
Private Sub MosaMosaAA()
Dim hConnection As ADODB.Connection
Set hConnection = New ADODB.Connection
hConnection.ConnectionString = _
"Provider=SQLOLEDB;" & _
"Data Source=Server;" & _
"Initial Catalog=NorthWind;" & _
"Integrated Security=SSPI;"
On Error GoTo CatchOpenException
Call hConnection.Open
On Error GoTo FinallyDispose
Dim hCatalog As ADOX.Catalog
Set hCatalog = New ADOX.Catalog
Set hCatalog.ActiveConnection = hConnection
Dim hTable As ADOX.Table
Set hTable = hCatalog.Tables("Orders")
Dim i As Integer
For i = 0 To hTable.Indexes.Count - 1
Dim hIndex As ADOX.Index
Set hIndex = hTable.Indexes(i)
If hIndex.PrimaryKey Then
Dim j As Integer
For j = 0 To hIndex.Columns.Count - 1
Call MsgBox(hIndex.Columns(j).Name)
Next j
End If
Next i
FinallyDispose:
If Not hConnection Is Nothing Then
If hConnection.State <> adStateClosed Then
Call hConnection.Close
End If
End If
Exit Sub
CatchOpenException:
Call MsgBox("データベース接続が確立できませんですた")
End Sub
|
_________________ C# と VB.NET の入門サイト
じゃんぬねっと日誌
|
- take
- 大ベテラン
- 会議室デビュー日: 2004/08/13
- 投稿数: 177
- お住まい・勤務地: 沖縄県北部
|
投稿日時: 2006-04-13 15:08
じゃんぬさん、ありがとうございます。
やりたい処理ができました。下のように関数化して使わせてもらってます。
自分的にかなり便利です。
コード: |
|
Function IsP_key(cat As ADOX.Catalog, TblName As String, FldName As String) As Boolean
Dim hTable As ADOX.Table
Set hTable = cat.Tables(TblName)
Dim i As Integer
For i = 0 To hTable.Indexes.Count - 1
Dim hIndex As ADOX.Index
Set hIndex = hTable.Indexes(i)
If hIndex.PrimaryKey Then
Dim j As Integer
For j = 0 To hIndex.Columns.Count - 1
If hIndex.Columns(j).Name = FldName Then
IsP_key = True
Else
IsP_key = False
End If
Exit Function
Next j
End If
Next i
End Function
|
あと、じゃんぬさんはベテランで経験も豊富なのでこんなこと質問
すること自体失礼だと思うのですが、どのようにして上のような
処理を実現するコードを調べたりするんでしょうか?
自分は恥ずかしながら自分で調べるも最後は掲示板で聞かないと解決
しないということが多々あるもので・・・。
|
- take
- 大ベテラン
- 会議室デビュー日: 2004/08/13
- 投稿数: 177
- お住まい・勤務地: 沖縄県北部
|
投稿日時: 2006-04-13 16:02
すみません、自分でコードをアップしておきながら不具合が
ありましたので修正しました。
コード: |
|
Function IsP_key(cat As ADOX.Catalog, TblName As String, FldName As String) As Boolean
Dim hTable As ADOX.Table
Set hTable = cat.Tables(TblName)
IsP_key = False
Dim i As Integer
For i = 0 To hTable.Indexes.Count - 1
Dim hIndex As ADOX.Index
Set hIndex = hTable.Indexes(i)
If hIndex.PrimaryKey Then
Dim j As Integer
For j = 0 To hIndex.Columns.Count - 1
If hIndex.Columns(j).Name = FldName Then
IsP_key = True
End If
Next j
End If
Next i
End Function
|
|
- じゃんぬねっと
- ぬし
- 会議室デビュー日: 2004/12/22
- 投稿数: 7811
- お住まい・勤務地: 愛知県名古屋市
|
投稿日時: 2006-04-13 16:07
引用: |
|
takeさんの書き込み (2006-04-13 15:08) より:
あと、じゃんぬさんはベテランで経験も豊富なのでこんなこと質問
すること自体失礼だと思うのですが、
|
実際に実行して確認ができれば良いのですが、今回のように試せないものは、
「試していません」と明記して、ちょっと逃げ道を作っていますw
そうでなくても、間違っていて他の回答者さんからフォロー受けることもあります。
ですので「ベテラン」だなんてとんでもないです。(;^-^)
引用: |
|
どのようにして上のような処理を実現するコードを調べたりするんでしょうか?
|
ほとんどリファレンスですね。
Microsoft 系、Sun Microsystems 系のものはネット上にゴロゴロしてますから。
(それ以外の場合も言語仕様書とか、まあリファレンス命ですね)
欲しい機能がどこにあるのかを知るには、ある程度数をこなす必要があると思います。
数をこなすと、ある程度のコモンセンスが磨きあがってきて、
「このクラス (オブジェクト) にはこのメンバがあるはずだ」という考え方ができるようになります。
_________________ C# と VB.NET の入門サイト
じゃんぬねっと日誌
|
- take
- 大ベテラン
- 会議室デビュー日: 2004/08/13
- 投稿数: 177
- お住まい・勤務地: 沖縄県北部
|
投稿日時: 2006-04-13 16:21
引用: |
|
じゃんぬねっとさんの書き込み (2006-04-13 16:07) より:
数をこなすと、ある程度のコモンセンスが磨きあがってきて、
「このクラス (オブジェクト) にはこのメンバがあるはずだ」という考え方ができるようになります。
|
なるほど。リファレンス&場数が命ということですね!
うーん・・・。ちょっと今の段階ではどこにリファレンスがあるのかも
わからない状態なのですが、VBの場合はMSDNを参照するとか
JAVAならSUNのクラスライブラリを参照するという認識で
いいのかなと理解してます。やっぱりそれ見てもある程度場数
こなしてないとなんのこっちゃさっぱり分からないですね。
助かりました。ありがとうございます。
|