こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

解決済みの質問

別のACCESSデータベースのテーブルのレコードを追加したいのです

別のACCESSデータベースのテーブルのレコードを追加したいのです

以前piroin654様にご指南頂き解決しましたが その後問題が発生しまして困っております

http://okwave.jp/qa/q5995365.html
レコードカウントで採番
rsInMain!番号 = rsInMain.RecordCount + 1
しておりましたが

1つのレコードを削除した場合、番号が重複してしまいます
そこで rsInMain!番号 = rsInMain!番号の最終行の値+1にしたいのですが
うまく行きません 何卒ご指南ください

投稿日時 - 2010-09-09 03:03:39

QNo.6169088

すぐに回答ほしいです

質問者が選んだベストアンサー

関数の最後のところを、

rs.Close: Set rs = Nothing
db.Close: Set db = Nothing
End Function

としてください。後始末が抜けていました。

投稿日時 - 2010-09-11 15:47:01

お礼

本当にありがとうございました
お陰様で完成いたしました。

日々勉強対します 本当に奥が深いです
ありがとうございました。 

投稿日時 - 2010-09-12 00:25:00

このQ&Aは役に立ちましたか?

9人が「このQ&Aが役に立った」と投票しています

回答(29)

ANo.28

関数を以下に変更してください。

'チェックの有無の確認
Private Function funcCheckExist() As Boolean
Dim db As Database
Dim rs As Recordset
Dim strSQL As String

strSQL = "SELECT T_データ.チェック FROM T_データ WHERE (((T_データ.チェック)=True))"
Set db = CurrentDb
Set rs = db.OpenRecordset(strSQL, dbOpenDynaset)
'チェックがすべて入っていない場合
If rs.RecordCount = 0 Then
funcCheckExist = True
'チェックが入っていないレコードが存在しない場合
Else
funcCheckExist = False
End If
End Function

投稿日時 - 2010-09-11 15:09:53

ANo.27

関数のほうを変更しなければならないので
関数を変更します。しばらくお待ちを。

投稿日時 - 2010-09-11 15:04:14

ANo.26

それでは、先ほどのコードの中で、

'チェックが入っていないレコードが存在するときの処理の確認

の以下のコードを以下のようにしてみてください。

If funcCheckExist = True Then
MsgBox ("チェックがすべて外れています。転送をせずに終了します")
Exit Sub
End If


これが効かないとちょいと大変なのですが。

それと、

>クエリで条件つけてフォーム表示してそこでチェックをいれさせ

のチェックはすべて同じテーブル、すなわちT_データのチェック
フィールドに入るようになっていますか。このチェックがT_テーブル
以外に入っているならば、チェックの有無の確認の関数の、

strSQL = "SELECT T_データ.チェック FROM T_データ WHERE (((T_データ.チェック)=False))"

の部分を変える必要があります。そのときはフォームのレコードソース
を直接参照するようにします。この場合、クエリだとクエリを参照
するようになります。

投稿日時 - 2010-09-11 14:47:39

ANo.25

確認ですが、
(1)
チェックが入ったものと入らないものが
混在している場合は転送の仕分けができている。

(2)
チェックが最初からすべてはずれていて、チェックを
入れたり外したりしない状態でクリックしても
転送されてしまう。

(3)
チェックが入っていたものをすべてはずして、
その直後にクリックすると転送されてしまう。

このような、状況ですか。
一度、提示したコードを入れずに、

Private Sub コマンド0_Click()
DoCmd.RunCommand acCmdSaveRecord

のように、クリック時の直後に
DoCmd.RunCommand acCmdSaveRecord
を挿入して試してみてください。
レコードの確定を先にしてみます。

投稿日時 - 2010-09-11 14:07:47

補足

ありがとうございます

DoCmd.RunCommand acCmdSaveRecordいれても 変化ありませんでした
(1)
チェックが入ったものと入らないものが
混在している場合は転送の仕分けができている。


(2)
チェックが最初からすべてはずれていて、チェックを
入れたり外したりしない状態でクリックしても
転送されてしまう。

(3)
チェックが入っていたものをすべてはずして、
その直後にクリックすると転送されてしまう。

このような、状況ですか。

はい そのとうりです

投稿日時 - 2010-09-11 14:29:18

ANo.24

補足の件了解しました。提示したコードでも
いいのですが、ちょいと検討してみます。

いいツールでしょう。しばらくトリツカレます。
以前提示したコードもこちらと同じインデントに
なると思います。

投稿日時 - 2010-09-11 12:49:13

ANo.23

以下のコードを、


'チェックが入っていないレコードが存在するときの処理の確認
If funcCheckExist = True Then
'Yesの場合はIf文を抜けそのまま転送プロセス
If MsgBox("チェックの入っていないレコードがあります。このまま転送しますか?", vbYesNo, "確認") = vbYes Then
'Noの場合はイベントの終了
Else
MsgBox ("転送をせずに終了します")
Exit Sub
End If
End If



Private Sub コマンド0_Click()
の直後、または、
Dim・・・
と変数宣言が終わった直後で、
Set dbOut = CurrentDbの前に入れてください。

これで処理に入る前にチェックの確認をします。
次に、以下の関数をフォームに張り付けてください。

'チェックの有無の確認
Private Function funcCheckExist() As Boolean
Dim db As Database
Dim rs As Recordset
Dim strSQL As String

strSQL = "SELECT T_データ.チェック FROM T_データ WHERE (((T_データ.チェック)=False))"
Set db = CurrentDb
Set rs = db.OpenRecordset(strSQL, dbOpenDynaset)
'チェックが入っていないレコードが存在する場合
If rs.RecordCount > 0 Then
funcCheckExist = True
'チェックが入っていないレコードが存在しない場合
Else
funcCheckExist = False
End If
End Function

投稿日時 - 2010-09-11 11:48:41

補足

わぁ
すいません 入れ違いです

投稿日時 - 2010-09-11 12:03:29

ANo.22

こういうことですか、もし転送する場合、チェックの入っていない
データが存在した場合、転送をストップして確認させる、
といことですか。

その場合、先にチェックの入っていないデータの有無を
先に確認し、もしなければ転送のプロセスに入る。
もし、存在すれば転送プロセスに入る前にYes Noを
聞いてYesならば、転送、Noならば転送プロセスに
入らずにすべての処理をしないままクリックイベント
を終了する、ということでいいのでしょうか。

投稿日時 - 2010-09-11 02:09:46

補足

ありがとうございます
ホント良いツールです 色々試しています

ところで
If rsOutMain!チェック = True Thenの件ですが
状態としましては
チェックフィールドの規定値をFalseに クエリで条件つけてフォーム表示してそこでチェックをいれさせ
転送ボタンをつくり 押すことによってチェックの入ったものを転送させていますが
まったくチェックの入っていない状態で転送処理しても処理が進んでしまいますので
何処にもチェックが入っていない場合処理を中止して "チェックが入っていません"のエラーメッセージを出したいのですが

すべてのボックスにチェックが入らなかった場合のみ転送プロセスに入らずにすべての処理をしないままクリックイベントを終了する

なのです

よろしくお願いいたします

投稿日時 - 2010-09-11 12:00:37

ANo.21

まちがえました。

If rsOutMain!チェック = False Then

ではなく、

If rsOutMain!チェック = True Then

があってもチェックがあるなしに関わらず
すべて処理されてしまう、といことですか?

投稿日時 - 2010-09-11 01:58:41

ANo.20

ツールは私も使っています。これでフリーですからね。
世の中にはもっとすごいフリーのものもあります。
まったく知られていないのですが、Access2003から
付属するオブジェクトの依存関係を示す2000版で、
ユニオンクエリ、サブクエリでもクエリをテーブル
まで分解してTreeiew表示し、Treeをレポート
表示するものです。海外でも似たようなものは
ありますが、調べてみると未完成で使い物には
なりませんでした。ただ、作者がまだ一般公開
していないのですが。

ところで、

>すべてのチェックボックスにチェックが入っていなくても転送処理
してしまう。

ということのようですが、

If rsOutMain!チェック = False Then

があっても処理されてしまう、ということですか?
「チェック」はT_データのフィールドのYes/Noフィールドの
名前をさすのですが。

投稿日時 - 2010-09-11 01:54:58

ANo.19

それから、先ほどのツールはOFFICE2000から2003が対象
なので、OFFICEのバージョンによっては機能しかも
しれません。

投稿日時 - 2010-09-10 21:10:14

補足

ツールありがとうございました
すごいのがありますね

チェックボックスの件ありがとうございます

表現がまずく すいません
すべてのチェックボックスにチェックが入っていなくても転送処理しますので
それを止めるエラーメッセージの事なんです
(教えていただいていて 申し訳ありません)

投稿日時 - 2010-09-11 00:55:43

ANo.18

If MsgBox("番号" & i & " 項目1" & rsOutMain!項目1 & " 項目2" & rsOutMain!項目2 & "のチェックがOFFになっています。転送しますか?",

のように、メッセージボックスの中の書き方は
これでお判りになると思いますが、フォーム
などに表示したデータが多い場合はメッセージ
ボックスが出ている間は、フォームを操作できないので
チェックの入っていないレコードの中身の確認の
ためにレコードの内容をメッセージボックスに
入れて確認します。確認内容をもっと表示したい
場合はメッセージボックスに追加します。

それから、追加したコードで、

rsOutMain.Edit
rsOutMain!チェック = True
rsOutMain.Update

はテーブルのチェックをONにして、削除対象に
設定するためのコードです。

投稿日時 - 2010-09-10 21:05:31

ANo.17

遅くなりました。
さきほどのANo.15については確認できたでしょうか。

チェックが無い場合のメッセージについては以下のように、

'T_データのエクスポート
rsOutMain.MoveFirst
Do Until rsOutMain.EOF

'チェックがOFFの場合の確認
If rsOutMain!チェック = False Then
i = rsOutMain!番号
If MsgBox("番号" & i & " 項目1" & rsOutMain!項目1 & " 項目2" & rsOutMain!項目2 & "のチェックがOFFになっています。転送しますか?", vbYesNo) = vbYes Then

rsOutMain.Edit
rsOutMain!チェック = True
rsOutMain.Update
DoCmd.RunCommand acCmdSaveRecord

End If
End If


If rsOutMain!チェック = True Then
i = rsOutMain!番号



Do Until rsOutMain.EOF

If rsOutMain!チェック = True Then
i = rsOutMain!番号
の間に 「'チェックがOFFの場合の確認」 以下を
挿入してください。



プログラムの上達の一つにコードを見やすく整理する、
ということがあります。そのためにはインデントを
適切に設定する、つまり段落です。そのためのいい
フリーのツールがあります。

http://www.oaltd.co.uk/Indenter/Default.htm

この、Office版を落とし、インストールします。
使い方は、カーソルが点滅しているプロシージャ
の部分のインデントを設定する場合はIndent Procedure
をクリックします。あとは見ての通りです。英語版ですが
機能だけは抜群です。
このようなものを利用してコードを見やすく、理解しやすい
ようにします。でも試行錯誤とエラーとの出会いと歯軋り
が一番の上達です。

それから、T_番号を使用する場合は、Loopの内側で更新しないと
いけないのでANo.27は変更する必要があった、ということを
添えておきます。

投稿日時 - 2010-09-10 20:53:57

ANo.16

>チェックボックスにチェックが入っていない時に
>メッセじを出して再入力を即するには どうしたらよいでしょうか

これがありましたね。ちょっと所用ができましたので
後ほど回答します。

投稿日時 - 2010-09-10 12:14:55

ANo.15

いろいろ消したり書いたりしたので、
どこかでコードの一部が欠落した可能性が
ありそうですが、

チェックボックスがOnになっている場合は

'T_データのエクスポート(データベース2からデータベース1へ)
rsOutMain.MoveFirst
Do Until rsOutMain.EOF
If rsOutMain!チェック = True Then

のところの、
If rsOutMain!チェック = True Then
で判断しますが、これが無くなっていませんか。

これを確認してください。それとこれを復活させると
Loopに対するDoが無い、というエラーが出るかも知れません。
したがって、

End If
rsOutSub.MoveNext
Loop

のところの、

End If

が抜けているかもしれません。

確認してみてください。

投稿日時 - 2010-09-10 12:10:58

ANo.14

これは、先にテーブルの最大値を読み込んでおいて、
その値をホーム側でnumMaxに保持し、レコードを一つ送る
毎にnumMaxを更新して次のレコードの番号に割り当てる
方法です。

投稿日時 - 2010-09-10 03:21:44

補足

ありがとうございました
出来ました

やはり 自分の頭では無理のようです
自分でがんばってみようと自分なりに考えていましたが
ご指南頂いたらすぐに解決いたしました

勉強がんばります

ところで すいません その後気付いたのですが 送る側のチェックボックスにチェックが入っていなくても
処理されてしまいます
チェックボックスにチェックが入っていない時にメッセじを出して再入力を即するには どうしたらよいでしょうか よろしくお願いいたします。

投稿日時 - 2010-09-10 10:37:07

ANo.13

すみません。

rsInMain.AddNew
rsInMain!番号 = rsInNUM!番号 + 1
rsInMain!項目1 = rsOutMain!項目1
rsInMain!項目2 = rsOutMain!項目2
j = rsInMain!番号
rsInMain.Update
numMax = numMax + 1

のように、
numMax = numMax + 1
を追加してください。

これで、重複がなくなると思います。

投稿日時 - 2010-09-10 03:12:12

ANo.12

もし、反応が悪ければもう一つ表示します。

投稿日時 - 2010-09-10 02:32:04

ANo.11

numMax = 0

はこの場合は必要ないので、コメントアウト
しておいてください。
初期化のつもりで入れたのですが、いらないです。

投稿日時 - 2010-09-10 01:58:18

ANo.10

ANo.27のコードをもとに進めます。

(1)
フォームのコード表の一番上にところで、

Option Compare Database
Option Explicit

となっているところに、

Option Compare Database
Option Explicit
Dim numMax As Long

のように、
Dim numMax As Long
を追加してください。

(2)
次に、

Set rsInNUM = dbIn.OpenRecordset("T_番号", dbOpenDynaset)

の下に、

numMax = 0
numMax = funcMax

を追加してください。
Set rsInNUM = dbIn.OpenRecordset("T_番号", dbOpenDynaset)
は使っていないのでコメントアウトするかしておいてください。

また、コードの下のほうの

'T_番号の更新
rsInNUM.Edit
rsInNUM!番号 = rsInNUM!番号 + 1
rsInNUM.Update
End If
rsOutMain.MoveNext
Loop

も、同様ですね。


(3)
rsInMain!番号 = rsInNUM!番号 + 1



rsInMain!番号 = numMax + 1

に変更してください。

(4)
以下の関数をはりつけてください。

Private Function funcMax() As Long
Dim db As Database
Dim rs As Recordset
Dim strSQL As String

Set db = DBEngine.Workspaces(0).OpenDatabase("C:\データベース1.mdb")
strSQL = "SELECT Max(T_データ.番号) AS 最大番号 FROM T_データ"
Set rs = db.OpenRecordset(strSQL, dbOpenDynaset)

funcMax = rs!最大番号
rs.Close: Set rs = Nothing
db.Close: Set db = Nothing
End Function

この関数で、"C:\データベース1.mdb"はファイルへのパスです
から環境に合わせて変更してください。

"SELECT Max(T_データ.番号) AS 最大番号 FROM T_データ"
のT_データは名称変更がなければそのまま使ってください。



以上です。少し試行錯誤をしていた案なのですが、
ようやくピンときたので、確認してみました。


これで確認してみてください。

投稿日時 - 2010-09-10 01:51:01

補足

ありがとうございます

さっそく試しましたが
やはり 重複エラーになります
テーブルのデータをみるとデータは転送されていて それをもう一度読むので
重複になっているようです??

もう少しがんばってみます

投稿日時 - 2010-09-10 02:33:34

ANo.9

えーっと、何だかいい案ができました。
確認したら表示します。どうやら
ご希望に沿えそうです。

投稿日時 - 2010-09-10 01:26:38

補足

ありがとうございます
お待ちしています。

私なりにも考えていましたが 中々上手くいきません
やはり 勉強が足りません
よろしく願い致します。

投稿日時 - 2010-09-10 01:35:43

ANo.8

別の方法がないこともないのですが、
データの同期をとるのがなかなか難しい状態です。

T_番号を使うのが一番確実なのですが、T_番号のフィールドの
中で「最後の番号=番号の最大」を表示しているフィールドは
ないのでしょうか。

T_番号にフィールドを追加、あるいはT_データの番号の最大値を
保持するテーブルを作るにしろ、確実にT_データの番号の更新を
反映できればそれでいいのですが。

少し、考えさせてください。

投稿日時 - 2010-09-10 01:10:33

ANo.7

>(T_番号テーブルで他のこともしていますので)

T_番号テーブルが事情により使えない、ということですか?

投稿日時 - 2010-09-09 23:18:46

補足

フィールドを3つ持たせて クエリで追加させて並べ替えていますので 値が異なるのです
別にカウント用のテーブルを作った方が良いのでしょうか

うまく表現出来なくてすいません

投稿日時 - 2010-09-09 23:39:21

ANo.6

T_番号の更新の位置を以下に変更してみてください。


'T_データのエクスポート(データベース2からデータベース1へ)
rsOutMain.MoveFirst
Do Until rsOutMain.EOF
If rsOutMain!チェック = True Then
'T_データに紐付けられたT_データ明細レコード検出用
i = rsOutMain!番号
'データベース1のT_データへのレコードの追加
rsInMain.AddNew
rsInMain!番号 = rsInNUM!番号 + 1
rsInMain!項目1 = rsOutMain!項目1
rsInMain!項目2 = rsOutMain!項目2
j = rsInMain!番号
rsInMain.Update

'T_番号の更新
rsInNUM.Edit
rsInNUM!番号 = rsInNUM!番号 + 1
rsInNUM.Update

投稿日時 - 2010-09-09 22:49:52

補足

ご指南ありがとうございます

rsInNUM!が 使えないんです T_番号値とT_データの番号は同じではないので (別の作業の関係で)
rsInMain!番号の最大値に+1をする方法をご指南頂ければ幸いなのですが

なにかとご面倒をお掛け致しますがよろしくお願いいたします

投稿日時 - 2010-09-09 23:33:34

テーブルA:

_id. fld1
001, AAAA
002, BBBB
003, CCCC

テーブルAにfld1='DDDD'を追加する場合のidの値は004です。

求め方1=レコード数+1---->3+1=4
求め方2=id最大値+1------>3+1=4

テーブルA:

_id. fld1
001, AAAA
002, BBBB
003, CCCC
004, DDDD

このテーブルAからid=3のレコードを削除。

テーブルA:

_id. fld1
001, AAAA
002, BBBB
004, DDDD

テーブルAにfld1='EEEE'を追加する場合のidの値は005です。

求め方1=レコード数+1---->3+1=4
求め方2=id最大値+1------>4+1=5

このように、求め方1では既存レコードが削除された場合にはid値が重複するという不具合が発生します。
この不具合を回避するには、求め方2を採用します。
仮に、扱うデータ量は10万件単位と膨大な場合には、求め方3へ移行することになります。

求め方3:採番テーブルを使う。

採番テーブルにid名とid最大値を記録します。
データを追加する場合には、このid最大値を使い、同時にid最大値を更新します。
レコードを1件登録する都度に最大値を求めるとデータ量によっては処理速度に問題がでます。
採番テーブルは、大量データを登録する際に有効で、自分でルリアル番号を管理・発生させる仕組みです。

ちくっと、横から失礼しました。

投稿日時 - 2010-09-09 15:33:58

ANo.4

追加ですが、コード中にあるように番号を
保持するテーブルT_番号を使います。一応
確認をしておいてください。

投稿日時 - 2010-09-09 08:08:58

ANo.3

排他などずいぶん苦心されたことと思います。

本題ですが、
対象のテーブルとは別に、もう1つ同じレコード数の番号のみ格納するテーブルを作れば?

その番号のみのテーブルは、本テーブルのレコードが削除された場合でも削除しなければ、そちらでレコードカウントがとれるでしょ。

投稿日時 - 2010-09-09 08:02:33

ANo.2

http://okwave.jp/qa/q5995365_2.html#answer
のANo.27のコードで、

'データベース1のT_データ明細へのレコードの追加
rsInSub.AddNew
rsInSub!番号 = j
rsInSub!名前 = rsOutSub!名前
rsInSub!住所 = rsOutSub!住所
rsInSub!電話 = rsOutSub!電話
rsInSub.Update
End If
rsOutSub.MoveNext
Loop
'T_番号の更新
rsInNUM.Edit
rsInNUM!番号 = rsInNUM!番号 + 1
rsInNUM.Update

の部分を、

'データベース1のT_データ明細へのレコードの追加
rsInSub.AddNew
rsInSub!番号 = j
rsInSub!名前 = rsOutSub!名前
rsInSub!住所 = rsOutSub!住所
rsInSub!電話 = rsOutSub!電話
rsInSub.Update
End If
rsOutSub.MoveNext
'T_番号の更新
rsInNUM.Edit
rsInNUM!番号 = rsInNUM!番号 + 1
rsInNUM.Update
Loop

のように、位置を変えてください。これで
rsInMain!番号 = rsInNUM!番号 + 1
で、rsInMain!番号が更新されると思います。

確認してみてください。

投稿日時 - 2010-09-09 07:58:08

補足

piroin654様 ありがとうございます
また 皆々様ありがとうございます 早速のご指南 誠にありがとうございます
色々やっていますが うまく行きません (T_番号テーブルで他のこともしていますので)

そこでrsInMainのT_データの番号フィールドの最大値に+1を考えていますが
うまく行きません


苦戦中です......
ご指南頂ければ幸いです

投稿日時 - 2010-09-09 21:51:37

ANo.1

同じ構造の2つのmdbファイルがあるわけですよね。んでそれらのレコードのみを1つにまとめたいと。連番のところが別のテーブルと関係があるならちと難しいことになりそうに思います。

連番が他のテーブルと関係ないこと前提ですけど、もしそうであればそんな面倒くさいことしなくてもこんな方法はどうでしょうか。

1、テーブルを開いて全体をコピー
2、エクセルにペースト
3、もう1つのmdbのコピーして、エクセルにペースト
4、連番のとこだけ削除
5、削除したところに列を挿入。ドラッグで連番振り直し
6、エクセルの表全体を、アクセスの該当テーブルにコピー

投稿日時 - 2010-09-09 03:51:14

あなたにオススメの質問