recordsetclone

先日、accessのフォームを作成中
表示されたデータでテーブルを更新しようと・・。

ソースのクエリが複雑で面倒くさい。
フォームの値をそのまま使おうと、こういう時はme.recordsetだよなと・・

しかし動作時にカーソルが動きすぎてみっともない。で、この時ハッとrecordsetcloneてこういう時のためににあるのかな?と気が付きました。

違っているかもしれないですが書き留めておきます。

ACCESSのレコードロック

バックエンドSQLserver リンクテーブルでaccessのクエリでフォーム作成している。
クエリのレコードロックを全部にすると他者はレコードを見ることもできない。
編集レコードロックはロックしないと同じ挙動。

Accessのエディターのフォント

MSACCESSのツール、オプションからエディタの設定でフォントを変えようとすると

フォントを選ぶコンボボックスの矢印が隠れて出てこない。
4Kディスプレイの高DPIスケーリング問題が原因のようです。解像度を一度落とすか、MSACCESS.EXEのプロパティ、互換性、高DPI設定の変更、スケーリングを上書きのところシステムにしてチェック入れる。

Access ヒントテキスト

Accessのフォームでヒントテキストを初めて使ったのですが

開発機 windows server 2016 で Access2016のフォームでテキストボックスのヒントテキストが表示できません。
コマンドボタンは表示されます。
コマンドボタンのヒントが出た状態でマウスを素早く該当テキストボックスへスライドさせると表示されます。

いろいろ試してもダメで諦めてaccde作成、クライアントでruntime版で動かすと問題なく動きます。

ちょっとベンチ

バックエンドSQLserverフロントエンドAccessVBA VS VB.NET
‘VBA
Public Function Queryspeedtest()
Dim T1 As Double
Dim T2 As Double
T1 = Timer
Dim cn As ADODB.Connection
Dim rs As ADODB.Recordset
Set cn = New ADODB.Connection
Set rs = New ADODB.Recordset

cn.ConnectionString = “OLEDB接続文字”
cn.Open
rs.cursorlocation=adUseClient
rs.Open “select A.code,B.codename from TableA as A inner join TableB as B on(A.code=B.code)”, cn, adOpenStatic, adLockOptimistic

rs.Close
cn.Close

T2 = Timer
Debug.Print T2 – T1
End Function

‘VB.NET
Public Shared Function Queryspeedtest()
Dim SW = New System.Diagnostics.Stopwatch()
SW.Start()

Dim cn = New System.Data.OleDb.OleDbConnection(OLEDB接続文字)
cn.Open()
Dim cmd = New System.Data.OleDb.OleDbCommand(
“select A.code,B.codename from TableA as A inner join TableB as B on(A.code=B.code)”, cn
)
Dim DT = New DataTable(“test”)
Dim adp = New System.Data.OleDb.OleDbDataAdapter(cmd)
adp.Fill(DT)
adp.Dispose()
cn.Close()

SW.Stop()
Debug.WriteLine(SW.Elapsed)
End Function

tableAは20万件、TableBは1万件弱のマスターファイル
TableAのレコードのcodeからTableBのcodenameを得るよくあるクエリ
もちろん主キーは両方あり

単純なselect column from tableは若干VBが勝利
上記のクエリはVBA 0.4s NET 0.8s

倍とはいえ差はコンマ数秒なのでまあいいかと思うがdatagridviewでtextbox表示とかcomboboxに入れたりするとちょっと・・
Accessフォームの方が速い、VB.NETではちょっと工夫が要りそうな

vbaでcursolocationがクライアントの時はcursoltype、locktypeによる差はない
サーバサイドでは最速と覚えていたadopenforwardonlyよりadopendynamicの方がなぜか早かった

ADODBとADO.NETはまったく別物なので比較するなと言われそうだけど・・
でもVSのエディタはすばらしい、VBAエディターが残念に思えるほど

datatable のクエリ

が遅い

sqlserverテーブルのシンプルな選択クエリ。
フォームに表示が遅いのではなく デザイナーで作成途中の確認の段階で遅い。

accessから移行中のクエリだがaccessのリンクテーブルのクエリの方がはるかに速い

ADODBのデータソースレス接続の様にコードにクエリを書いてdataadapter作成したほうが速いのか?

ODBC接続のaccessクエリに ADO.NETが速さで劣る?

どこか間違えているのかも、明日落ち着いて見直そう

サロゲートペア SQLserverの場合

以前もMySQLで書いたけど
AccessからSQLServerへサロゲート文字保存について

AccessはVBエディターに表示はできないけどテーブル、フォームに表示保存可能
SQLserverも保存できる

接続文字を書いてexecuteメソッドで
insert into Table(column) values(“サロゲートペア文字”)
とVBAから更新クエリ発行すると保存できない

OLEDBはだめ
oledbはhttps://docs.microsoft.com/ja-jp/sql/connect/oledb/features/utf-16-support-in-oledb-driver-for-sql-server?view=sql-server-2017
難しいけどだめだと書いてあるようです

ODBCならといろいろ試したけどこれも今のところだめです
ODBCからリンクテーブルにしてフォーム作って入力すると可能なのだがなぜ?
接続文字列にオプションか何かあるのかな?引き続き要調査

Accessのサブフォームのカウント

親フォームに子フォームのレコード数を表示させたい あるいは取得して何かに利用したい
ってことは良くあることと思います。

サブフォームのレコードソースと同じようにレコードセットを取れば取得はできるでしょうけど
フォームでもできるはずだと検索すると
forms!親フォーム!子フォームの名前.form.recorsetclone.recordcount
で出てくるとあるがなぜかだめ
フォームデザインでビルドで入力してもインテリセンスのメンバーにrecordsetもrecordsetcloneも出てこない

VBAで
forms(親フォーム)(子フォーム).form.recordsetclone.recordcount
と書けば取得できるのだが

なぜ?

集計クエリ カウント

重複は除外してカウント、重複あっても全カウント 両方出したいとき
SQLserver、MySQLなら
select GroupColumn,Count(distinct TargetColumn),Count(TargetColumn) from Table group by GroupColumn
と簡単に出る

ACCESSでは?

このクエリはACCESSではできないようなのでいろいろ試したが今のところクエリ一文ではできていない
一度クエリでカウントして保存してさらにこれをソースにカウントしたカラムをカウントする のイメージで….

select GroupColumn as Group1,Count(TargetColumn) as Count1 from Table group by GroupColumn,TargetColumn
これをQ_1で保存して
select Group1,Count(Count1) as CountDistinct from Q_1 group by Group1
これでdistinct countができる

もう一つ全カウント
select GroupColumn as Group1,Count(TargetColumn) as CounAll from Table group by GroupColumn
のクエリQ_2を保存して

Q_1、Q_2 の連結クエリを作成する  の2段構え
もっといい方法があるのかもしれないが今のところこれしか思いつかない

バックエンドがSQLserverやMySQLならACCESSから一番上のパススルークエリの方が楽かな?