テキスト出力

VBAからテキスト出力はこうしてましたが

Dim TestStr As String
TestStr = “テキスト文字”
Dim Num As Long
Num = FreeFile

Open “c:\TESTopen.txt” For Output As Num
Print #Num, TestStr
Close Num

こういう方法もあります

Dim Stream As ADODB.Stream

Set Stream = New ADODB.Stream
Stream.Mode = adModeReadWrite
Stream.Type = adTypeText
Stream.Charset = “Shift_JIS”
Stream.LineSeparator = adCRLF
Stream.Open

Stream.WriteText TestStr, adWriteLine
Stream.SaveToFile “C:\TESTstream.txt”, adSaveCreateOverWrite
 Stream.Close

openメソッドで出力できるのはshift_jisだけかな
adodb.streamは上のオプションshift_jisをUTF-8にすればUTF-8出力もできます。
ただオプションで出力テキストが微妙に違ってきます。
うちの環境では上と同じテキストを出力するにはこのオプションでした。

CursorLocation CursorType LockType

recordsetプロパティが意図通りにならないことがあるのはわかりました。

https://blogs.msdn.microsoft.com/nakama/2008/10/16/ado/
の下の方に表が出ています。
SQLserverの場合だと思います。

同じようにMysql5.7で調べてみると

結果がSQLserverと少し違います。

赤文字は意図と結果が違う
斜めはSQLserverと結果が違う

aduseclientにした時点でstatic決定は同じでした。
aduseserverでstaticになってますがrecordset.countは-1でした。

CursorLocation CursorType

前回の続き vbaからsqlserverへ
Dim cn As ADODB.Connection
Dim rs As ADODB.Recordset
Set cn = New ADODB.Connection
 cn.ConnectionString = “SQLserver接続文字列”
 cn.open
Set rs = New ADODB.Recordset
 rs.CursorLocation = adUseClient ’前回はcnにしたけど今回はrs

rs.open “select・・・・”,cn,adopendynamic,adlockoptmistic
debug.print rs.recordcount
debug.print rs.cursortype

で返らないと思ったrecordcountがちゃんと返るのですが
rs.cursortypeを見るとどうもadopendynamicになってない

でこういうサイト見つけました
http://d.hatena.ne.jp/replication/20090312/1236866953
マイクロソフトのヘルプはリンク切れ

カーソル位置でカーソルタイプが決まる?のようです
adopendynamic adopenforwardonly がサーバサイド
adopenstatic adopenkeyset がクライアントサイド

adUseClientを明示したらadopenstaticが決定するのかな?

では今までほとんど明示していないのでデフォルトのサーバーサイドカーソルでadopenkeysetも矛盾あり?実はdynamicになっていた?
MysqlとSQLserverでも挙動に違いがありそうです。

カーソル位置とカーソルタイプとロックタイプは齟齬がないように組み合わせないと意図したようになってない可能性ありですか

難しいですrecordset

日付

dateadd(Y,1,CURRENT_TIMESTAMP)
というのをネットで見つけた

実際にクエリ発行してみると

select dateadd(Y,1,CURRENT_TIMESTAMP) は 2018-04-03 20:52:17.357

明日になる・・Yって何?
では
select format(CURRENT_TIMESTAMP,’Y’) は 2018年4月

うーむ
調べるとYはdayofyaer の略で年始からの日数

ここで謎だったVBAの
debug.Print format(now,”Y”) が 92 なのだが
これがSQLserverのdayofyearに当たることに気がついた。

ならば SQLserverの
select format(CURRENT_TIMESTAMP,’Y’) は 92 になってほしい所だが
なぜか
2018年4月

SQLserverの一時テーブルへの接続は競合しないのか?

答えはしないです。
フロントAccessでDBアプリを開発中ですが不安になりました。
レコードセット取らずにcn.executeで直接#テーブルいじってますので・・
クライアント2台で試してみました。

cn.Execute “drop table if exists #no123”
cn.Execute “select カラム into #no123 from テーブル where カラム like ‘%ほにゃらら%'”
rs.Open “select * from #no123”, cn, adOpenKeyset, adLockOptimistic
rs.MoveFirst
Do Until rs.EOF
MsgBox rs!カラム
rs.MoveNext
Loop

一台で操作途中でもう一台から同操作
競合するならdropされるはずですが大丈夫でした。
このときSQLserverはどうしているのかというと

一時テーブルが2つ出来ていました。
これは便利です

まだまだあった件数取得

こういうのもありですか
rs.Open “select count(主キー) as MyCount from テーブル where条件”, cn, adOpenStatic, adLockOptimistic
Debug.Print rs!MyCount

引き出しが少ないのでネタが尽きます
というか備忘録なのでご勘弁を

rs.Rcordcountは必ずしも遅くなかった

rs.recordcountが遅いかもの件です
5万件ぐらいのテーブルで確認してみました。
where条件にもよるのでしょうけど

rs.Open “select id from テーブル where条件”, cn, adOpenStatic, adLockOptimistic
Debug.Print rs.RecordCount

rs.Open “select id from テーブル where条件”,cn, adOpenStatic, adLockOptimistic
rs.Move first
i = 1
Do Until rs.EOF
rs.MoveNext
i = i + 1
Loop
Debug.Print i

はrs.recordcountの2馬身ぐらいで勝ちでしたが

rs.Open “select id from テーブル where条件”, cn, adOpenStatic, adLockOptimistic
Debug.Print rs.RecordCount

rs.Open “select id from テーブル where条件”,cn, adOpenForwardOnly, adLockReadOnly
rs.Move first
i = 1
Do Until rs.EOF
rs.MoveNext
i = i + 1
Loop
Debug.Print i

はloopの圧倒的勝利でした。

rs.addnew rs.update など流れの中で件数取得ならrecordcount
件数取得だけが目的ならloopということかな?

vba二次元配列訂正再掲

Public Function theFailureTest()
Dim Ary() As String
ReDim Ary(0, 3)
Ary(0, 0) = “a”
Ary(0, 1) = “b”
Ary(0, 2) = “c”
ReDim Preserve Ary(1, 3)
Ary(1, 0) = “d”
Ary(1, 1) = “e”
Ary(1, 2) = “f”
Debug.Print UBound(Ary, 1)
Debug.Print UBound(Ary, 2) 
End Function

これはダメな例
なぜダメかはあとで・・
次に正しい例
Public Function theSuccessTest()
Dim Ary() As String
ReDim Ary(3, 0)
Ary(0, 0) = “a”
Ary(1, 0) = “b”
Ary(2, 0) = “c”
ReDim Preserve Ary(3, 1)
Ary(0, 1) = “d”
Ary(1, 1) = “e”
Ary(2, 1) = “f”
Debug.Print UBound(Ary, 1)
Debug.Print UBound(Ary, 2)
End Function
拡張できるのは最後の次元だけなので添字の変数は2番目に置く
理由は難しそうだが

に書いてあります

vba二次元配列訂正

以前に二次元配列の順番がどうこうの事
一方を添字の変数にして
For i=0 to なんてやるのでああ書きましたが
順番は関係ないですね。
表を縦にして見るか横にして見るかみたいなもので
どちらもうまくいくはず
うまくいかないのは他の問題。

failureとsuccessが逆
単純な間違いでした。
やはり順番大事

思い出した、rs.recordcountは

Rs.recordcountは件数が多いと遅くてイライラした記憶が。

Dim i as long,MyCount as long

rs.movefirst
i=1
do until rs.eof
rs.movenext
i=i+1
Loop
MyCount=i

コードが長くなるけどこちらが速かったような