set mya=createobject("adodb.connection")
myb="接続先フルパス"
with createobject("excel.applcation")
set myc=.workbooks.add.activesheet.range("a1")
.visible=true
end with
mya 接続文字列
.open
set myd=.execute("クエリ名")
myc.copyfromrecordset myd
end with
Function splith(str As String, n As Long) As String()
'//ANSI(半角1バイト、全角2バイト)を利用してnカウント以内で分割した文字列の配列を返す関数
Dim strBase As String, strAnsi As String, str1 As String, str2 As String, strLeft As String
Dim sCount As Long
Dim strSplit() As String
strBase = str
Do Until strBase = ""
ReDim Preserve strSplit(sCount)
strAnsi = strConv(strBase, vbFromUnicode)
'//合計nカウント以内だったらそのまま取り出して終わり
If LenB(strAnsi) <= n Then
strSplit(sCount) = strBase
Exit Do
End If
'//nカウント目の文字をチェックして2バイト文字なら切り捨てる
str1 = strConv(LeftB(strAnsi, n), vbUnicode)
str2 = strConv(LeftB(strAnsi, n + 1), vbUnicode)
If Len(str1) = Len(str2) Then
'//2バイト文字から1バイト取り出したら文字数は1(文字は化けるが文字数は1)
'//余分に1バイト取り出しても正常な文字として文字数は1で、全体の文字数は変わらない
'//nカウント目の文字が2バイト文字の前半1バイトだったので1バイト減らす
strLeft = strConv(LeftB(strAnsi, n - 1), vbUnicode)
Else
'//余分に1バイト取り出して文字数が変わったらnカウントでちょうど文字の区切りだった
strLeft = str1
End If
'//取り出した文字を配列に保存
strSplit(sCount) = strLeft
'//取り出した文字分だけ元の文字を取り除く
strBase = Mid(strBase, Len(strLeft) + 1)
'//配列の次の要素の準備
sCount = sCount + 1
Loop
splith = strSplit()
End Function
テストコード
Private Sub コマンド0_Click()
Dim strBase As String
Dim strSplit() As String
Dim sCount As Long
strBase = Me!テキスト
If strBase = "" Then Exit Sub
If strBase <> strConv(strConv(strBase, vbFromUnicode), vbUnicode) Then
MsgBox "非対応の文字が見つかりました。処理を中断します"
Exit Sub
End If
strBase = strConv(strBase, vbNarrow)
strSplit() = splith(strBase, 20)
For sCount = 0 To UBound(strSplit)
Debug.Print strSplit(sCount)
Next
End Sub
Public Function MidAnsiB(S As String, M As Long, L As Long) As String
Dim res As String, T As Long
If S = "" Then Exit Function '元テキストが空なら終了
If LenAnsiB(S) <= L Then '元テキストが任意の数以下ならそのまま出力して終了
MidAnsiB = S
Exit Function
End If
res = StrConv(MidB$(StrConv(S, vbFromUnicode), M, L), vbUnicode) 'コードを変えて文字数揃えてユニコードに戻す
res = Mid$(S, M, Len(res))
If LenAnsiB(res) > L Then
res = Mid$(S, M, Len(res) - 1)
End If
'サロゲートペア文字対策
Select Case AscW(Right$(res, 1))
Case &HD800 To &HDBFF
res = Left$(res, Len(res) - 1)
End Select
MidAnsiB = res
End Function
関連するコントロール(参照しているコントロール)の近くの空いている所に配置してます。
隙間がないとき、「最背面に移動」で関連するコントロールの背面に隠してます。
関連するものがないときは、適当に空いている所に配置します。
また、非表示コントロールが分かりやすいように背景色を薄いピンクにしてます。
ちなみにcount関数は値の数を数えるので、今月のデータ数を数えるのであればsumのほうが良いと思うのですが。
Count関数
また、集計関数を使う場合、ヘッダーやフッターに設定している他の集計関数でエラーがあると
まとめてすべて「#エラー」と表示されるようなのでご注意ください。
(サンプル作っててALLエラーが出ると思ったらこれでしたorz
なるほど。フィールド名にしていたつもりでしたが、テキストボックスと同一になっており、テキストボックス名を見に行っていたようです。
テキストボックス名を変更したらうまくいくようになりました。ありがとうございました。
[月] はレコードソースに含まれるフィールド名ですか。
テキストボックス名だとエラーになります。
集計関数の引数の式は、フィールド名を含まないとエラーになります。
(フィールドを対象に集計するものなので)
WEB検索すればサンプルコードは見つかると思いますので、試してみては。
あるいは、
手動でそのMDBへのリンクテーブルを作成することはとできますか。
できるなら、DoCmd.TransferDatabase メソッドでリンクテーブルを作成すればどうでしょうか。
いろいろ、試してみてダメな場合、
ネットワーク環境に依存する問題だと思いますので、同じ環境を用意できないこちらからはこれ以上のアドバイスは難しいですね。
たまたま、同じようなエラーを経験した人が見てればヒントは出せるかもしれませんが。
この件について、改めて質問させていただきたく投稿致します。
「F管理」を「F管理総合」から開くときと、直接他フォームの履歴から開くパターンがあります。
他フォームから開くときは「F管理総合」を開いていないのでエラーが起きるのですが、
「F管理総合」から開くときもあるので下記コードは残したいです。
条件分岐できますでしょうか。
大変申し訳有りません。今日手動でいじってみた所odbc に接続が失敗しました、というエラーが出て開けませんでした。一台のパソコンからのみ開く事が出来る様です。開けたのは旧システムのmdbファ
イルでした。この状態は、どう言う状態でしょうか?
オンラインの状態のmdbファイルです。属性n、オフラインでの使用不可になっています。プロパティの詳細です。セキュリティタブが無かったためフルアクセスは、無理そうです。daoだと接続出来ますか?ご教示お願い致します。
daoは分かりません。どの様な情報が足りないでしょうか?宜しくお願い致します。
その情報だけからは、ちょっと原因は分からないです。
DAOでやってみる。
リンクテーブルにしてみる。
SQLでIN句で接続してみる。
など、他の方法も試してみては。
set mya=createobject("adodb.connection")
myb="接続先フルパス"
with createobject("excel.applcation")
set myc=.workbooks.add.activesheet.range("a1")
.visible=true
end with
mya 接続文字列
.open
set myd=.execute("クエリ名")
myc.copyfromrecordset myd
end with
此れがコードです。スマホで書いています。すみません
確かに、言われてみると新規フォームではないですよね。。
今後は正確な用語をお伝えするよう、気を付けます。ご指摘ありがとうございます。
お騒がせいたしました。
なるほど。。全く別の種類の会社データなのでまとめるという発想が全くありませんでした。
検討してみます!ご提案ありがとうございます。
企業情報が格納されているテーブルが2つあるということでしょうか。
ユニオンクエリで一つの纏めることはできます。
フィールド構成が同じなら、クエリのSQLビューで下記のように記述します。
できれば、分けずに最初から一つのテーブルに纏めておいた方がいいです。
ユニオンクエリは重いし、更新できないなど、制限がありますので。
一つに纏めておいて、分割したデータが欲しいときはクエリの抽出条件で分けるようにします。
そのエラーがでるコードを提示してください。
「新規フォームを作って移動してしまうことがある」というのは、ひょっとして
「新規レコードへ移動してしまうことがある」という意味のつもりだったのかな?
だとしたら既定の動作ですね。
このような言葉だけでやりとりする場合は、用語は正確に使うというのは重要ですので、まずは正確な用語を理解して使うように意識しましょう。
それが目的なら、「新規追加禁止」にするのがベストな解決策ですね。
ありがとうございます。おたずねするまで、特殊な事例とは思わず深く考えていなかったのですが
結局、データを増やしたくないフォームだったので、勝手にレコードが増えたりして不便だったため
(本当は全部非連結にしたいが、レポート作成のため連結にしているフォーム)
新規追加禁止で対応し、解決しました。
別で同じような事例が起きた場合、改めてご報告させていただくかもしれません。
ネット上には残らないので安心してください。私のところだけにメールで届きます。
特に変わった設定をしたつもりはないのですが…。
ちなみに参考までにファイルをお送りした場合、ネット上にずっと残る形になりますか?
別にまずいデータが入っているわけではないんですが、なんとなく。
そんなことがあるのですか。
Enterだけで新規フォームを作ってしまうのですか。
通常の設定ではそんなことはないと思いますが。
どのような設定をしているのですか。
おそらく「F管理総合」フォームを開いていなかったようです・・そういうことですね。
ありがとうございました。
バッチリうまくいきました。ありがとうございます😊
txtB
は「txtB」という名前のコントロール(またはフィールド)そのものを参照します。コントロール名を動的に生成して参照するなら、文字列を受け取ってコントロールを参照するようなアクションを使う必要がありますそれと、計算順の問題で数値部分は先に計算させる(括弧で囲む)必要がありますね
更に初心者の質問で申し訳ありません。
Debug.Print strSplit(sCount)
の部分についてですが、テキストボックスに1個ずつ格納していきたいと思っています。
テキストボックス名 txtB & scount + 1 として
txtB & sCount + 1 = strSplit(sCount)
というのは、不可能のようですね。。
変数名のカウントアップはどうしたらよいのでしょうか。
大変悩んでいたので本当に助かります。
じっくり内容を確認し、勉強させていただきます!!本当にうれしいです。
ありがとうございます。
hatenaさん
返信ありがとうございます。
Excel
新規ブックを開いて、
A1セルに 00LJ と入力
B2セルに AU87 と入力
上記のセルをそれぞれコピーして、Accessのテーブルのフィールドに貼り付け
⇒上記手順を試したところ、新規で作成したエクセルのデータは問題なく貼付できました。
使用しようとしているエクセルデータの方に、何かしら問題があるのかもしれません。
エクセル側データを今一度確認し、問題がないようなら、
0始まりおよびアルファベットから始まるフィールドが関与しない方法で
クエリを作成するなど他の対応方法を検討してみます・・・
とりあえずUnicodeのことは忘れて、次の例を考えます。
この場合、たとえば
Midh(str, a, b)
のような関数を作ったとしてMidh("あイうエお", 5, 3)
としたとき、「う」はどう扱ったらいいでしょうか?半角を1、全角を2とカウントするようなMidのような関数は現実的ではないでしょう
このようなことをする場合は、すべての文字をひとくくりに考える必要があります
半角を含む文字列を処理する関数「splith()」
テストコード
出力結果
ありがとうございました。
全然違いますね。。
他も試してみたのですがやはりうまく行きません😓
Len(M)の間違いでした。。
あと、初心者で申し訳ないのですが、
$マークは、どういう意味があるのでしょうか?
お騒がせしております。
今気づいたのですが、
res = Mid$(S, M, Len(res))
が
res = Mid$(S, LenAnsiB(M), Len(res))
でしょうか。。
あとで試してみます。
ID 毎の標準偏差を求めたいなら、クエリのデザインビューは下記にしてください。
ID以外のフィールドをグループ化しますと、グループ内件数が1件になってしまうので標準偏差は求められません。
SQLなら、
連結にしていましたが、[元テキスト]⇒txt元テキスト ・・・等々変更したら1回で表示されるようになりました。教えていただきありがとうございました。
反映させる部分↓
ありがとうございます。教えていただいた関数を参考に考えていますが、
行き詰っています。
今回文章を何個かに分割したいので、midで作って繰り返しさせたいと思っていますがうまくいきません・・・
どこが間違っているのでしょうか。
(とりあえず汎用関数の部分のみ↓)
全角、半角に関しては、いろいろ複雑な事情があります。
とりあえず下記を参照してください。
半角1桁全角2桁で計算するLenB、LeftB関数の代替関数 - hatena chips
VBA Unicode 文字の入力や変換、読み込みについて
Unicode文字(Shift-JISにない文字)、サロゲートぺー文字の扱いはどうするのかまずは決める必要があると思います。
フォームは連結ですか、非連結ですか。
一応、非連結で下記のようなサンプルを作成して確認してみましたが、ボタン1回クリックで表示されました。
テキストボックス
コマンドボタン
この件ですが、21バイトだった場合19バイトで切り出したらいいですね・・
式を考え中ですが、また相談させていただくと思います。すみません。
5の質問について、解決法がわかれば助かります。
もう1つの質問を記載させていただきます。
現在以下のように、[テキスト]の文章を20バイトで区切ってテキストボックスで3つに分けるという処理をしています。
このとき、うまく20バイトずつ文章が分かれてくれたらいいのですが
全角と半角が混ざった文章だと、文字化けしたり21バイトになったりします。
20バイト以下で、文字化けせずにうまくわけることはできませんでしょうか。
以上、ご検討いただければ幸いです。宜しくお願い致します。
下記コードで半角化&文字数を表示することができました!
ありがとうございました。
次の質問なのですが、現在ボタンを2回押さないと反映できません。
(それを解消できるかと思って「Me.Refresh」を2回入れているのですが・・だめでした)
1回で反映できる方法はありますでしょうか。