回答編集履歴

2

追記

2016/05/12 10:15

投稿

kaz.Suenaga
kaz.Suenaga

スコア2037

test CHANGED
@@ -44,7 +44,7 @@
44
44
 
45
45
  ---
46
46
 
47
- (2016/05/12 14:07 のコメントの続きです。)
47
+ ##(2016/05/12 14:07 のコメントの続きです。)
48
48
 
49
49
 
50
50
 
@@ -101,3 +101,201 @@
101
101
 
102
102
 
103
103
  に置き換えれば動作するでしょう。
104
+
105
+
106
+
107
+
108
+
109
+ ---
110
+
111
+ ##(2016/05/12 18:57 のコメントの続きです。)
112
+
113
+
114
+
115
+ > >変数の「参照渡し」と「値渡し」を知っていますか
116
+
117
+ > javaの資格を取る際に、勉強したので意味としてはわかります。
118
+
119
+ >
120
+
121
+ > >↓の2つのコードの違いを理解できますか。
122
+
123
+ >  Dim cn As New ADODB.Connection
124
+
125
+ >  Dim cn As ADODB.Connection
126
+
127
+ >
128
+
129
+ > 実はこれは以前から気になっていたのですが、ネットなどでサンプルコードをみると、
130
+
131
+ >  Dim cn As ADODB.Connection
132
+
133
+ >  の方は、後ほど変数にNEWを代入してインスタンス化していますが、
134
+
135
+ >  Dim cn As New ADODB.Connection
136
+
137
+ > と初めから宣言しているとその後のインスタンス化は不要なのかなぁ…と、
138
+
139
+ > ぼんやりとしかわからないので気になっていました。
140
+
141
+
142
+
143
+ あ、じゃあ説明はしやすいですね。
144
+
145
+
146
+
147
+ VBAの場合、大前提として Dim は変数の定義です。
148
+
149
+ その際、オブジェクト型の変数の場合、 New をつけることで同時にインスタンス化されます。
150
+
151
+
152
+
153
+ 細かいことを抜きにして、
154
+
155
+
156
+
157
+ ```VBA
158
+
159
+ Dim obj as New object ' 型宣言とインスタンス化を同時に行う
160
+
161
+ ```
162
+
163
+
164
+
165
+ ```VBA
166
+
167
+ Dim obj as object ' 型宣言
168
+
169
+ Set obj = New Object ' インスタンス化
170
+
171
+ ```
172
+
173
+
174
+
175
+ は同義です。
176
+
177
+
178
+
179
+
180
+
181
+ オブジェクト型以外のほとんどの変数の場合、VBAでは変数の代入は値渡しで行われるのですが、オブジェクト型の場合は参照渡しで行われます。
182
+
183
+
184
+
185
+ ```VBA
186
+
187
+ Dim obj1 As Object
188
+
189
+ Dim obj2 As Object
190
+
191
+
192
+
193
+ Set obj1 = New Object
194
+
195
+ Set obj2 = obj1
196
+
197
+ ```
198
+
199
+
200
+
201
+ この場合、変数 obj2 は obj1 への参照となります。
202
+
203
+ つまり obj2 への操作は obj1 にも影響します。
204
+
205
+
206
+
207
+ ```VBA
208
+
209
+ Dim obj1 As Object
210
+
211
+ Dim obj2 As Object
212
+
213
+
214
+
215
+ Set obj1 = New Object
216
+
217
+ Set obj2 = New Object
218
+
219
+
220
+
221
+ Set obj2 = obj1
222
+
223
+ ```
224
+
225
+ この場合、動作は結局一緒なのですが、obj2 として生成されたインスタンスは、obj1 への参照に上書きされ消えます。
226
+
227
+ (実動上は無駄なだけなはず)
228
+
229
+
230
+
231
+ で 2016/05/12 14:57 のコメントにあった下記のソースの
232
+
233
+ ```VBA
234
+
235
+ Dim cn As New ADODB.Connection 'SQLserverへの接続 
236
+
237
+ ● Dim cn2 As New ADODB.Connection 'Accessへの接続
238
+
239
+ Dim rs1 As New ADODB.Recordset
240
+
241
+ Dim rs2 As New ADODB.Recordset
242
+
243
+ Dim rs3 As New ADODB.Recordset
244
+
245
+
246
+
247
+ Dim strConnectionString As String 'SQLServer接続文字列
248
+
249
+
250
+
251
+ strConnectionString = CStr(DLookup("connectionString", "接続文字列テーブル", "ID= 2"))
252
+
253
+ ●Set cn2 = CurrentProject.Connection
254
+
255
+
256
+
257
+ cn.Open strConnectionString
258
+
259
+ ●’cn2.Open ←ここでは実行時エラー'3705'「オブジェクトが開いている場合は、操作は許可されません」とエラーが出る為一旦コメントアウト中です。
260
+
261
+         この記述は、不要もしくは違う箇所に書かなければなりませんか?ご教示いただければ幸いです。
262
+
263
+
264
+
265
+ rs1.Open "顧客マスタ", cn, adOpenForwardOnly, adLockReadOnly //エラー
266
+
267
+ ● rs2.Open "Q売上", cn2, adOpenForwardOnly, adLockReadOnly
268
+
269
+ ● rs3.Open "Q売上明細", cn2, adOpenForwardOnly, adLockReadOnly
270
+
271
+ ```
272
+
273
+
274
+
275
+ `cn2.Open` でエラーが出る理由は、`Dim cn2 As New ADODB.Connection` としてインスタンスを生成したものの、その後で `Set cn2 = CurrentProject.Connection` をすることにより、cn2 はCurrentProject.Connection への参照となっています。
276
+
277
+
278
+
279
+ つまりいま開いているAccessファイルへの接続なので、さらにOpenはできないため、エラーが出ます。
280
+
281
+
282
+
283
+ ```
284
+
285
+ Dim cn2 As ADODB.Connection
286
+
287
+ Set cn2 = CurrentProject.Connection
288
+
289
+ ```
290
+
291
+ で、cn2 は既に開いたAccessDBへの接続になっているわけです。
292
+
293
+
294
+
295
+
296
+
297
+
298
+
299
+ という事でほぼ理解上は解決するのではないでしょうか。
300
+
301
+

1

追記

2016/05/12 10:15

投稿

kaz.Suenaga
kaz.Suenaga

スコア2037

test CHANGED
@@ -39,3 +39,65 @@
39
39
 
40
40
 
41
41
  まずそこからいってみましょう。
42
+
43
+
44
+
45
+ ---
46
+
47
+ (2016/05/12 14:07 のコメントの続きです。)
48
+
49
+
50
+
51
+ 1つのソースコードの中でSQLServerにもAccessにも接続したいのか、SQLServerへの接続はAccessのリンクテーブルを通じて行うのかで回答が変わりますが、仮に後者の場合、
52
+
53
+
54
+
55
+ > ADOのコードに
56
+
57
+ > Set cn = CurrentProject.Connection
58
+
59
+
60
+
61
+ が正解です。
62
+
63
+ 元のソースコードの
64
+
65
+
66
+
67
+ ```VBA
68
+
69
+ Dim cn As New ADODB.Connection
70
+
71
+
72
+
73
+ Dim strConnectionString As String 'SQLServer接続文字列
74
+
75
+
76
+
77
+ strConnectionString = CStr(DLookup("connectionString", "接続文字列テーブル", "ID= 2"))
78
+
79
+
80
+
81
+ cn.Open strConnectionString
82
+
83
+ ```
84
+
85
+
86
+
87
+ が、
88
+
89
+
90
+
91
+ ```VBA
92
+
93
+ Dim cn As ADODB.Connection
94
+
95
+
96
+
97
+ Set cn = CurrentProject.Connection
98
+
99
+ ```
100
+
101
+
102
+
103
+ に置き換えれば動作するでしょう。