ちょっとベンチ

バックエンド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が速さで劣る?

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

datagridviewでキャレット位置取得

こちらはたいへんでした
Accessのように簡単にいきませんでした
あちこち調べて
On Error Resume Next

Dim TexteditCtrl As DataGridViewTextBoxEditingControl
TexteditCtrl = DirectCast(DataGridView1.EditingControl, DataGridViewTextBoxEditingControl)
Dim tb As DataGridViewTextBoxEditingControl = CType(TexteditCtrl, DataGridViewTextBoxEditingControl)
Dim startP As Long
Dim str As String
Dim strCount As Long
startP = tb.SelectionStart

str = “文字”
strCount = Len(str)

tb.SelectedText = str
tb.SelectionStart = startP + strCount

でなんとか取得して同位置に代入できますがキャレット位置はコマンドボタンのクリックイベントではできない
というかキャレットが消えてしまう
ここはAccessと同じです
なのでこれはラベルのクリックイベント ラベルのボタン加工はAccessよりはるかに難しい
VSも良いですがAccessの良さも再認識してます

新元号

新元号は令和
Accessには和暦はあるのでそのうちupdateあるでしょう
SQLserverとVB.NETにはない → 失礼、VB.NETにはあります
SQLserverのスカラー関数を
前略
DECLARE @ResultVar nvarchar(10),@VarYear int,@VarDate nvarchar(10),@VarDateInt int

select @VarYear=cast(format(@paramDate,’yyyy’) as int)
select @VarDate=format(@paramDate,’MM/dd’)
select @VarDateInt=cast(format(@paramDate,’yyyyMMdd’) as int)

— Add the T-SQL statements to compute the return value here
select @ResultVar=(case
when @VarDateint>20190430 then
concat(‘R’,format((@VarYear-2018),’00’),’/’,@VarDate) –令和
when @VarDateInt>19890107 then
concat(‘H’,format((@varyear-1988),’00’),’/’,@VarDate) –平成
when @VarDateInt>19261224 then
concat(‘S’,format((@varyear-1925),’00’),’/’,@VarDate) –昭和
when @VarDateInt>19120729 then
concat(‘T’,format((@varyear-1911),’00’),’/’,@VarDate) –大正
when @VarDateInt>18680124 then
concat(‘M’,format((@varyear-1867),’00’),’/’,@VarDate) –明治
else ‘0’
end
)
— Return the result of the function
RETURN @ResultVar
以下略
これで良いはず
SQLserverにあればVSはなんとかなるでしょう
VB.NETには和暦あります。省略型はないですが。

VB.NET始めました

プログラムの.netへの移行はじめました
オブジェクトとかクラスとかインスタンスとか幽霊のようなものを勉強しないといけません

あえて枝葉末節から
VBAで使っていた資産が使えるのか?
html workshop で作ったchmファイルはVBAの物をそのまま使いますが
Alias.h と Map.h を追加
Aliasに
topic1=index.html
Mapに
#define topic1 100
等書いてworkshopプロジェクトに追加してコンパイル

VB.NETでフォームにコンポーネントからhelpproviderをdrug&drop
プロパティのhelpnamespaceにchmファイルのパス入力
ヘルプボタン作成しクリックイベントは
Help.ShowHelp(Me, “chmのパス”, HelpNavigator.TopicId, “100”)

まだ方法あると思いますがとりあえずです。

文字

文字は良くわからないです

VBAのasc関数で asc(“文字”) は 文字のshift_jisコードを返すようですがなぜそれがascなのかよくわかりません

甘んじて受け入れて
SQLserverにはasc関数はない、ascii関数がある。ではこれはutf8かutf16コードを返すのだろうと妄想するとこれは間違い
アスキーコードを返す

SQLserverにはunicode関数がある。調べると文字のunicodeを返すと出てくる。unicodeは文字の集合でコードではないと覚えたけどと混乱

SQLserverで
unicode(‘、’)は12289
VBAで
ascw(“、”)は12289
12289は16進数にすると3001でコード表では「、」のutf16コード
ますます混乱

うちの環境では
VBAのasc関数はsjisのコード ascw関数はutf16のコードが返ってくる
SQLserverのascii関数はunicodeを返すらしいがutf16のコードと同じ値が返ってくる
ではunicode=utf16なのかというとそうではないと覚えていたのだが・・
宿題にします。

複数ステップのOLEDBエラー nvarchar(max) 改行

SQLserverテーブルのnvrachar(max)のカラムに対して
ODBC接続のレコードセット取って

Str=”文字” & vbCrLf
rs!カラム=Str
rs.update
など更新や追加行うと複数ステップの・・・エラー

OLEDB接続では起きない
nvarchar(max)をmaxを500など変更すれば起きない
cn.execute “insert into・・・values・・・” では起きない

サロゲートペア 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からリンクテーブルにしてフォーム作って入力すると可能なのだがなぜ?
接続文字列にオプションか何かあるのかな?引き続き要調査

OLE DB

詳しくはわかりませんが何年か前から
Microsoft OLE DB Provider for SQL Server(SQLOLEDB) 
はもうサポートしないから新規開発に使用するのはやめてほしい
とMicrosoftがアナウンスしているが今でも使えています
でも突然消えると困るので調べてみると
代わりに
Microsoft OLE DB Driver for SQL Server(MSOLEDBSQL) 
をリリースしてるようです
問題はSQLOLEDBはOSに付属してるので何も考えずに良かったけどMSOLEDBは別途インスト必要らしいです
挙動も少し違うようで安全性は向上する、計算列の操作が今まで甘かったけど今度は厳しく行きますよ という感じのことがアナウンスされてた
今日開発機にインストして使ってみましたがaccdbは特に問題なく動きました。
OSは64bitですがAccessが32なのでx86をインストだろうと思ったらX64でした
接続文字もSQLOLEDBをMSOLEDBSQLに書き換えるだけで良いようです
アプリ配布先にはインストされてないのでパッケージ作るとき困るけどSQLOLEDB消えてから考えよう