[リストへもどる]   [VBレスキュー(花ちゃん)]
一括表示

投稿時間:2007/05/31(Thu) 17:33
投稿者名:こう
Eメール:
URL :
タイトル:
データグリッドから削除
お世話になります。

データグリッドにDBからのデータを表示させています。
表示は、権限によりそれぞれ表示が分かれるようになっています。
それを削除する際に、例えば「2007年」で削除してしまうと表示されていない
「2007年」のデータまで消えてしまいます。
それは困るのでSQL文を考えて対処しようとしていますが、長くなりそうなので
データグリッドに出てるものだけから選択して削除は出来ないかなと思いまして質問しました。

データグリッド自体を操作するのは出来ないです。
あくまでも、コマンドボタンによる操作で行いたいです。

もしあれば教えていただけるとうれしいです。

投稿時間:2007/05/31(Thu) 19:57
投稿者名:魔界の仮面弁士
Eメール:
URL :
タイトル:
Re: データグリッドから削除
> 表示は、権限によりそれぞれ表示が分かれるようになっています。

この「表示を分ける」部分がどのように作りこまれているか、にもよりますが、
思いつくところでは、データグリッドに渡している Recordset の Delete メソッドを呼ぶ、とか。

投稿時間:2007/06/01(Fri) 10:56
投稿者名:こう
Eメール:
URL :
タイトル:
Re^2: データグリッドから削除
> この「表示を分ける」部分がどのように作りこまれているか、にもよりますが、
> 思いつくところでは、データグリッドに渡している Recordset の Delete メソッドを呼ぶ、とか。

お返事ありがとうございます。
Recordset の Delete メソッドを呼ぶのを試してみましたが、
「オブジェクトまたはプロバイダは要求された操作を実行できません。」
とエラーが出てしまいます。
何とか対処法はないでしょうか?

投稿時間:2007/06/01(Fri) 11:21
投稿者名:魔界の仮面弁士
Eメール:
URL :
タイトル:
Re^3: データグリッドから削除
> 「オブジェクトまたはプロバイダは要求された操作を実行できません。」
> とエラーが出てしまいます。

Recordset は、削除可能なモードになっていますか?
開いた後の CursorLocation / CursorType / LockType が
どうなっているかを確認してみてください。

投稿時間:2007/06/01(Fri) 11:53
投稿者名:こう
Eメール:
URL :
タイトル:
Re^4: データグリッドから削除
> Recordset は、削除可能なモードになっていますか?
> 開いた後の CursorLocation / CursorType / LockType が
> どうなっているかを確認してみてください。

度々すみません、こちらのページを参考にしてコードを書いたのですがうまくいきません。
CursorLocation / CursorType / LockType の設定も下記ページのようにしています。
http://www.red.oit-net.jp/tatsuya/vb/ADO.htm#Delete

投稿時間:2007/06/01(Fri) 14:37
投稿者名:魔界の仮面弁士
Eメール:
URL :
タイトル:
Re^5: データグリッドから削除
> こちらのページを参考にしてコードを書いたのですが
まず確認。削除のために、新たに Recodset を開いたのでしょうか?
それとも、DataGrid に渡している Recordset そのものに対して Delete したのでしょうか?

> うまくいきません。
具体的には、どうなってしまうのでしょう?

> CursorLocation / CursorType / LockType の設定も下記ページのようにしています。
> http://www.red.oit-net.jp/tatsuya/vb/ADO.htm#Delete
なるほど、静的カーソルですか。では、CursorLocation はどちら側ですか?

それと、そのレコードセットに主キー列が含まれているかも確認してください。

投稿時間:2007/06/01(Fri) 15:01
投稿者名:こう
Eメール:
URL :
タイトル:
Re^6: データグリッドから削除
> まず確認。削除のために、新たに Recodset を開いたのでしょうか?
> それとも、DataGrid に渡している Recordset そのものに対して Delete したのでしょうか?
新たに Recodset を開いています。ただ、コードが重複しますので、近いうちに
DataGrid に渡している Recordset そのものに対して Delete しようと思います。

> > うまくいきません。
> 具体的には、どうなってしまうのでしょう?

    'コネクションをオープン
    mCn.Open
    'レコードセットをオープン
        mRs.Open StrSQL, mCn, adOpenDynamic, adLockPessimistic, adCmdText
    
        mRs.Delete   ← ここの部分でエラーが発生します。

> なるほど、静的カーソルですか。では、CursorLocation はどちら側ですか?
  CursorLocation は、 adUseClient にしています。

> それと、そのレコードセットに主キー列が含まれているかも確認してください。
  主キー列は含まれています

投稿時間:2007/06/01(Fri) 15:08
投稿者名:魔界の仮面弁士
Eメール:
URL :
タイトル:
Re^7: データグリッドから削除
> 新たに Recodset を開いています。
DataGrid の方にしないと、元の「SQL文を考えて対処しようとしていますが」の状況に
戻ってしまうような気が…。

> > > うまくいきません。
> > 具体的には、どうなってしまうのでしょう?
>  mRs.Delete   ← ここの部分でエラーが発生します。
具体的には、どのようなエラーになってしまうのでしょう?

> > なるほど、静的カーソルですか。では、CursorLocation はどちら側ですか?
>   CursorLocation は、 adUseClient にしています。
クライアント側ですか。
では、『If RS.Supports(adDelete) Then』が True となりますか?

投稿時間:2007/06/01(Fri) 15:37
投稿者名:こう
Eメール:
URL :
タイトル:
Re^8: データグリッドから削除
> DataGrid の方にしないと、元の「SQL文を考えて対処しようとしていますが」の状況に
> 戻ってしまうような気が…。
ですよね・・。それに気づいてグリッドの方にしようと思いました。

> 具体的には、どのようなエラーになってしまうのでしょう?
「オブジェクトまたはプロバイダは要求された操作を実行できません。」
と出ます。

> では、『If RS.Supports(adDelete) Then』が True となりますか?
False になります

投稿時間:2007/06/01(Fri) 16:19
投稿者名:こう
Eメール:
URL :
タイトル:
Re^9: データグリッドから削除
> > DataGrid の方にしないと、元の「SQL文を考えて対処しようとしていますが」の状況に
> > 戻ってしまうような気が…。
> ですよね・・。それに気づいてグリッドの方にしようと思いました。

グリッドの方に修正して削除したところ、最初の一行のみ削除されるようになりました。
これでは、望む削除ではないですが少しは進んだのかなと思います

投稿時間:2007/06/01(Fri) 17:27
投稿者名:こう
Eメール:
URL :
タイトル:
Re^10: データグリッドから削除
> グリッドの方に修正して削除したところ、最初の一行のみ削除されるようになりました。
> これでは、望む削除ではないですが少しは進んだのかなと思います

その後、削除条件をループで回すことによって条件に当てはまるものが削除されるようになりました。
魔界の仮面弁士さん、色々教えていただいてありがとうございました。

投稿時間:2007/06/01(Fri) 17:28
投稿者名:魔界の仮面弁士
Eメール:
URL :
タイトル:
Re^10: データグリッドから削除
DataGrid が持つ Recordset そのものを直接操作するのではなく、
DataGrid が持つ Recordset の Clone に対して操作した方が安全かも。


> グリッドの方に修正して削除したところ、最初の一行のみ削除されるようになりました。

削除前に「削除したい行」に移動させてください。
移動のためには、MoveNext メソッドによる移動も使えますが、
DataGrid の『ブックマーク』を使って移動させることもできます。

・Recordset.Bookmark プロパティ … ブックマークによる移動に使う
・Recordset.Filter プロパティ … ブックマーク配列、またはWHERE条件による絞込みに使う

・DataGrid.Bookmark プロパティ … DataGrid の現在行のブックマーク
・DataGrid.SelBookmarks プロパティ … DataGrid で選択中な行のブックマーク一覧
・DataGrid.RowBookmark メソッド … DataGrid の、指定した行のブックマークを返す

投稿時間:2007/06/04(Mon) 11:48
投稿者名:こう
Eメール:
URL :
タイトル:
Re^11: データグリッドから削除
レスが遅れました。色々と情報ありがとうございます。参考になりまmす。
> DataGrid が持つ Recordset そのものを直接操作するのではなく、
> DataGrid が持つ Recordset の Clone に対して操作した方が安全かも。
生データそ操作するよりよさそうですね。検討してみます。
>
> 削除前に「削除したい行」に移動させてください。
> 移動のためには、MoveNext メソッドによる移動も使えますが、
> DataGrid の『ブックマーク』を使って移動させることもできます。
ブックマークによる方法も調べてみました。両方使えるようにしたいと思います。

金曜日うまくいくと書いたのですが後でテストしたところ、権限により全データ
の中から一部しか表示されていないものを削除しようとしたところ、
「更新に必要なベース テーブル情報が足りません。」
と出てしまいました。全データ表示の場合はエラーは発生しません。
この場合はSQL文がよくないのでしょうか?

投稿時間:2007/06/04(Mon) 13:43
投稿者名:魔界の仮面弁士
Eメール:
URL :
タイトル:
Re^12: データグリッドから削除
> 金曜日うまくいくと書いたのですが後でテストしたところ、権限により全データ
> の中から一部しか表示されていないものを削除しようとしたところ、
う〜ん、「権限」「一部」というのは、どのような状態なのでしょうか?
そちらの状況が読み取れませんので、より具体的な例を出していただけると助かります。

現象を再現できるよう、数行数列程度の小さな実験用テーブルを作って試してみて、
どういう SQL および VB のコードを書いたとき、その結果になってしまうのか、などと。


> 「更新に必要なベース テーブル情報が足りません。」
どのプロバイダを使っていて、どの DB 製品に繋いでいるのかすらわからないので、
具体的な解決策は出せませんが、もし静的カーソルでその状況になるのだとしたら、
rs.Fields(主キー列).Properties("BASETABLENAME").Value が取得できない状況なのかも。

投稿時間:2007/06/04(Mon) 14:11
投稿者名:こう
Eメール:
URL :
タイトル:
Re^13: データグリッドから削除
> う〜ん、「権限」「一部」というのは、どのような状態なのでしょうか?
> そちらの状況が読み取れませんので、より具体的な例を出していただけると助かります。
すみません。このような感じです。ローカル環境でオラクル9.0,win2000を使っています。
例)全データ(NO,区分は主キー)  
NUM NO 区分 名前        
1   1   1     A
2   1   2     A
3   2   1     B
4   3   2     B
5   4   3     B
6   5   2     C
7   6   3     C

権限により区分を2まで表示
NUM NO 区分 名前        
1   1   1     A
2   1   2     A
3   2   1     B
4   3   2     B
5   5   2     C

> rs.Fields(主キー列).Properties("BASETABLENAME").Value が取得できない状況なのかも。
調べてみたところ、区分を2までにした場合値がnull でエラーでしたので値が取得できていなさそうです。
全件表示した場合は値を取得しました。

Select Row_Number() over(NO, DIVISION)
NUM, NO, DIVISION, NAME from
(Select * from TEST Where  DIVISION <any '3')  
Where NUM = '1' OR  DIVISION = '' OR NAME = '' ORDER BY NUM;
多分、区分の部分を3未満に設定したからかなと思うんですが・・

投稿時間:2007/06/04(Mon) 16:01
投稿者名:魔界の仮面弁士
Eメール:
URL :
タイトル:
Re^14: データグリッドから削除
> 権限により区分を2まで表示

条件がそれだけであれば、分析関数は使わずとも、
 SELECT
  ROWNUM ROWINDEX,
  TEST.NUM,
  TEST.NO,
  TEST.DIVISION,
  TEST.NAME
 FROM
  TEST
 WHERE
  TEST.DIVISION < 3
 ORDER BY
  NUM, NO
で済むのでは? (少なくとも、10gでは削除できました)


> Select Row_Number() over(NO, DIVISION)
> NUM, NO, DIVISION, NAME from
> (Select * from TEST Where  DIVISION <any '3')  
> Where NUM = '1' OR  DIVISION = '' OR NAME = '' ORDER BY NUM;

OVER 句の書式、間違っていませんか?


> 多分、区分の部分を3未満に設定したからかなと思うんですが・・
その SQL のままだと無理じゃないですかね。
後付で RS.Properties("Unique Table").Value を設定しようにも、Oracle Provider が
インラインビューのスキーマ(BASETABLENAME)を得ることができないでしょうし。

投稿時間:2007/06/04(Mon) 17:32
投稿者名:こう
Eメール:
URL :
タイトル:
Re^15: データグリッドから削除
> 条件がそれだけであれば、分析関数は使わずとも、
> で済むのでは? (少なくとも、10gでは削除できました)
条件はもうちょっとありまして、絞込みも行うの分析関数で行おうと思います。

> OVER 句の書式、間違っていませんか?
本番用では無事検索出来るので大丈夫かと思いますが、再度確認してみます。
>
> その SQL のままだと無理じゃないですかね。
> 後付で RS.Properties("Unique Table").Value を設定しようにも、Oracle Provider が
> インラインビューのスキーマ(BASETABLENAME)を得ることができないでしょうし。
ですよね・・・。色々なところで使いまわしてるんですが、SQLの文を考え直してみます。
それで、対応できるものを探してみます。
色々親切に教えていただきありがとうございましたm(_ _)m

投稿時間:2007/06/04(Mon) 18:50
投稿者名:魔界の仮面弁士
Eメール:
URL :
タイトル:
Re^16: データグリッドから削除
> 条件はもうちょっとありまして、絞込みも行うの分析関数で行おうと思います。
絞り込み、というと、Recordset.Filter のことでしょうか。

> > > Select Row_Number() over(NO, DIVISION)
> > OVER 句の書式、間違っていませんか?
> 本番用では無事検索出来るので大丈夫かと思いますが、再度確認してみます。
うーん。当方ではエラーになりましたけど。ウィンドウ指定に ORDER BY 式がありませんし。

投稿時間:2007/06/05(Tue) 09:26
投稿者名:こう
Eメール:
URL :
タイトル:
Re^17: データグリッドから削除
おはようございます。
> 絞り込み、というと、Recordset.Filter のことでしょうか。
SQL文で行うつもりでしたが、Recordset.Filter についても調べてみます。
両者を比べて扱いやすい方にしてみます。

> うーん。当方ではエラーになりましたけど。ウィンドウ指定に ORDER BY 式がありませんし。
例に書いた文に ORDER BY 式 が抜けておりました。すみません・・・。

Select Row_Number() over(Order by NO, DIVISION)
NUM, NO, DIVISION, NAME from
(Select * from TEST Where  DIVISION <any '3')  
Where NUM = '1' OR  DIVISION = '' OR NAME = '' ORDER BY NUM;

投稿時間:2007/06/05(Tue) 10:01
投稿者名:こう
Eメール:
URL :
タイトル:
Re^18: データグリッドから削除
Recordset.Filterを使うことにより出来ました。
DIVISION <any '3'にあたる部分をif文で条件付けて
    
mRs.Open StrSQL, mCn, adOpenDynamic, adLockOptimistic, adCmdText
If Text01.Text = "01" Or _
    Text01.Text = "2A" Then  
Else
    mRs.Filter = "DIVISION <= 2"
End If

と言う具合です。昨日までRecordset.Filterを使うことなんて考えてませんでしたが
一気に出来てすごくうれしかったです。
魔界の仮面弁士さんありがとうございました!