Public Function Tab2Spaces(s As String, n As Long)
Dim lines: lines = Split(s, vbLf)
Dim l
For Each l In lines
Dim a: a = Split(l, vbTab)
Tab2Spaces = RTrim(Tab2Spaces) & vbLf
Dim i
For Each i In a
Tab2Spaces = Tab2Spaces & Format(i, "!" & String(n, "@"))
Next
Next
Tab2Spaces = Mid(Tab2Spaces, 2)
End Function
上記のコードを標準モジュールにコピーしてください。
A1セルにタブと改行を含むテキストを貼り付けます。その後、下記のコードを実行します。
Public Sub test()
Range("A2") = Tab2Spaces(Range("A1"), 8)
End Sub
SELECT
Left(T1.レースID馬,16) AS レースID1
,0 AS 返還フラグ
,4 AS 券種
,Val(Right(T1.レースID馬,2)) AS 軸2
,0 AS 空白
,100 AS 購入金額
,Null AS 空白2
,"A" AS 自信
,Left(T2.レースID馬,16) AS レースID2
,Val(T2.レースID馬,2)) AS ヒモ
FROM
MT_指数追加 AS T1 INNER JOIN MT_指数追加 AS T2
ON Left(T1.レースID馬,16) = Left(T2.レースID馬,16)
WHERE T1.順位=2 AND T2.順位=5;
SELECT
T1.[レースID]
,0 AS 返還フラグ
,4 AS 券種
,T1.[ゼッケン] AS 軸2
,T2.[ゼッケン] AS ヒモ5
,0 AS 空白
,100 AS 購入金額
,Null AS 空白2
,"A" AS 自信
FROM (
Q_指数買い目順位2 AS T1 INNER JOIN Q_指数買い目順位5 AS T2
ON T1.[レースID] = T2.[レースID]
)
ORDER BY T1.[レースID];
SELECT
クエリ1.,
クエリ2.
FROM
(SELECT
Left([レースID馬],16) AS レースID
,0 AS 返還フラグ
,4 AS 券種
,Val(Right([T1].[レースID馬],2)) AS 軸2
,0 AS 空白
,100 AS 購入金額
,Null AS 空白2
,"A" AS 自信
FROM MT_指数追加 AS T1
WHERE T1.順位=2
) As クエリ1 INNER JOIN
(SELECT
Left([レースID馬],16) AS レースID
,Val(Right([レースID馬],2)) AS ヒモ
FROM MT_指数追加 AS T2
WHERE T2.順位=5
) AS クエリ2
ON クエリ1.レースID = クエリ2.レースID;
問題なく作動します
ありがとうございます。
SELECT
T1.[レースID]
,0 AS 返還フラグ
,4 AS 券種
,Val(Right([T1].[レースID馬],2)) AS 軸2
,Val(Right([T2].[レースID馬],2)) AS ヒモ
,0 AS 空白
,100 AS 購入金額
,Null AS 空白2
,"A" AS 自信
FROM
(SELECT
FROM MT_指数追加 AS T1
WHERE T1.順位=2
) As AS T1 INNER JOIN
(SELECT
FROM MT_指数追加 AS T2
WHERE T2.順位=5
) AS AS T2
ON Left([T1].レースID馬,16) = Left([T2].レースID馬,16)
SELECT
Left(T1.レースID馬,16) AS レースID1
,T1.単勝人気
,T1.数値合計
,T1.順位
,T1.単勝オッズ
,Val(Right(T1.レースID馬,2)) AS ゼッケン1,
,Left(T2.レースID馬,16) AS レースI2
,T2.単勝人気
,T2.数値合計
,T2.順位
,T2.単勝オッズ
,Val(Right(T2.レースID馬],2)) AS ゼッケン2
FROM
MT_指数追加 AS T1 INNER JOIN MT_指数追加 AS T2
ON Left(T1.レースID馬,16) = Left(T2.レースID馬,16)
WHERE T1.順位=2 And T2.順位=5
ORDER BY T1.単勝人気, T1.順位, T2.単勝人気, T2.順位;
SELECT
クエリ1.*,
クエリ2.*
FROM
クエリ1 INNER JOIN クエリ2
ON クエリ1.レースID = クエリ2.レースID;
まず、これでご希望の結果になってますか。
なっているなら、クエリ1、クエリ2の部分をサブクエリSQLに変更するだけです。
SELECT
クエリ1.*,
クエリ2.*
FROM
(SELECT
・・・・
FROM ・・・・
WHERE ・・・・
) As クエリ1 INNER JOIN
(SELECT
・・・・
FROM ・・・・
WHERE ・・・・
) AS クエリ2
ON クエリ1.レースID = クエリ2.レースID;
クエリ1
SELECT
Left([レースID馬],16) AS レースID
,T2.単勝人気
,T2.数値合計
,T2.順位
,T2.単勝オッズ
,Val(Right([レースID馬],2)) AS ゼッケン
FROM MT_指数追加 AS T2
WHERE T2.順位=5
ORDER BY T2.単勝人気, T2.順位;
ありがとうございます。
素晴らしいです。確認させていただきます。
失礼しました。フォントがBoldになっておりまして、これを修正したら字面が合いました。
タブをスペースに変換する関数を作成してみました。
上記のコードを標準モジュールにコピーしてください。
A1セルにタブと改行を含むテキストを貼り付けます。その後、下記のコードを実行します。
実行後のシート↓
ご想像の通りでして、仰ることもごもっともです。
そうではありますが、どうしてもやりたいと思っていまして。
フォントはMSゴシックで、ひとまず下記のようにスペースを
埋めました。イミディエイトウインドウ上では全て字面が
合っているのですが、Excel上ではズレが生じています。
debug.print addSpace("AAA") & "BBB"
Cells(i,j).Value = addSpace("AAA") & "BBB"
debug.print Cells(i,j).Value
Function addSpace(strDept As String) As String
addSpace = strDept & Space(40 - LenB(strDept))
End Function
1セル内で表形式のような見栄えで表示したいということでしょうか。
最終目的は、印刷ですか。
VBAでスペースを適切に挿入するようにすれば可能だとは思いますが、
表計算ソフトのエクセルでやるようなことではないように思います。
ご回答ありがとうございます。
なるほどです。タブはあるがセル上、表示されていないということですね。
このセル内が横に複数列あり、 ひとつひとつのセル内にvbCrLfで改行を入れ、最大10数行程度になります。
そして、これらが数十から数百くらいの行で構成されています。
ですので、列ごとにタブを入れて、文字の左面を合わせたいというのが目的です。
単に複数の半角スペースを入れただけですと、この目的が達成できないのがご相談の真の内容です。
タブを1つもしくは2つ入れた場合のように、スペースを入れられれば解決するのですが、難易度が高く挫けております。
エクセルのセル内ではタブ文字は空白として表示できない仕様です。
下の画像は、上記のコードを実行したシートです。
セルでは空白はないですが、数式バーは空白(タブ)が表示されてます。
セルをコピーしてテキストエディターに貼り付けるとちゃんとタブは挿入されています。
つまり、タブが削除されるのではなく、タブはあるがセル内では表示されないということです。
セル内で空白を表示したいのなら、スペースを使うしかないです。
下記でうまくいきませんかね。
すいません、最初のクエリを、分けるつもりが、くっついてしましました。
見にくくて申し訳ありません。
hatena様
重ねての解答ありがとうございます。
やりたいことは下記のことです。
昨日は、
Q_指数買い目順位2⇒クエリ1
Q_指数買い目順位5⇒クエリ2
SELECT
クエリ1.,
クエリ2.
FROM
(SELECT
Left([レースID馬],16) AS レースID
,0 AS 返還フラグ
,4 AS 券種
,Val(Right([T1].[レースID馬],2)) AS 軸2
,0 AS 空白
,100 AS 購入金額
,Null AS 空白2
,"A" AS 自信
FROM MT_指数追加 AS T1
WHERE T1.順位=2
) As クエリ1 INNER JOIN
(SELECT
Left([レースID馬],16) AS レースID
,Val(Right([レースID馬],2)) AS ヒモ
FROM MT_指数追加 AS T2
WHERE T2.順位=5
) AS クエリ2
ON クエリ1.レースID = クエリ2.レースID;
SELECT
T1.[レースID]
,0 AS 返還フラグ
,4 AS 券種
,Val(Right([T1].[レースID馬],2)) AS 軸2
,Val(Right([T2].[レースID馬],2)) AS ヒモ
,0 AS 空白
,100 AS 購入金額
,Null AS 空白2
,"A" AS 自信
FROM
(SELECT
FROM MT_指数追加 AS T1
WHERE T1.順位=2
) As AS T1 INNER JOIN
(SELECT
FROM MT_指数追加 AS T2
WHERE T2.順位=5
) AS AS T2
ON Left([T1].レースID馬,16) = Left([T2].レースID馬,16)
このSQLを実行すると、FROM句の構文エラーとなります。
昨日はご不快な質問をして、申し訳ありませんでした。
今回記載したコードも全くとんちんかんな、コードでしょうか?
お手すきのときに回答いただけたら幸いです。
ちなみに、サブクエリを使わなくても、下記のようなSQLで同じ結果になりそう。
ばっとみて、SQLが無茶苦茶です。なにをしたいのか分かりません。
いきなりサブクエリを使った一つのSQLを作成するのではなく、
サブクエリ部分のクエリを単独で作成して、そのクエリを使ったSQLを作成します。
それで、希望の結果がでるのが確認出来たら、クエリをサブクエリのSQLに変更するというようにしましょう。
この文章通りのことをしたいのなら、下記のようなSQLになります。
まず、これでご希望の結果になってますか。
なっているなら、クエリ1、クエリ2の部分をサブクエリSQLに変更するだけです。
ただ、いまのスキルレベルなら無理にサブクエリにせずに複数のクエリを組み合わせて作成した方がメンテナンス性もいいように思います。
すいません
FROM MT_指数追加 AS T1 ⇒FROM MT_指数追加 AS T2
です。
ご回答誠にありがとうございます。
やり方的に正しいことが分かってスッキリしました。
Recordsetプロパティを使う方法ですか。その方法は残念ながら、レポートでは使えません。
Report.Recordset プロパティ (Access) | Microsoft Docsに下記の記述があります。
DAOなら可能なようです。ADOしかだめということなら、一時テーブルにインポートしてそれと連結するようにとのことです。
一時テーブルを使わずにという方法もありますが、かなり面倒な方法になりますので、一時テーブルを使う方法でいいのではと思います。
ご回答ありがとうございます。
なるほど、可能ではあるのですね。それが分かっただけでも嬉しいです。
フォームで表示させる場合はおおよそ以下のような感じです。
ADODBパススルーを行い、レコードセットを取得、「Me.Recordset」でフォームのレコードセットに受け渡し、これを表示させます。
これと同じ内容をレポートで行った場合、空欄になって表示できませんでした。
おそらくレポートでは「Me.Recordset」ではだめなのかと考えたのですが、結局実現できませんでした。
'接続用のクラスです
Dim db As DataBaseAccess
Dim mySQL As String
Dim rs As ADODB.Recordset
'データベースの接続処理
Set db = DatabaseFactory.creater
db.connect
'実行するクエリの文字列をセット。
mySQL = "SELECT " & _
"[取引先マスタ_ID] , [取引先コード], [取引先名]" & _
" FROM [dbo].[取引先マスタ]"
'実行してレコードセットに格納します。
Set rs = db.execute(mySQL)
'ここでデータソースに取得したDBの結果をセット
Set Me.Recordset = rs
'オブジェクト変数を終了、破棄します。
rs.Close
db.disconnect
Set rs = Nothing
Set db = Nothing
フォームではどのように直接表示させているのですか。
そのコードを提示してもらえますか。
レポートの場合は、フォームとは違いますので、フォームの方法をそのままではできないので、レポート用に改変する必要があります。もとのフォームのコードの提示があればそれをもとにアドバイスできると思います。
hatena様 回答ありがとうございました。
連結フォームからならレコードセットを開かず処理ができるのですね。初めて知りました。。。
またカレントレコードの処理も勉強になりました。テーブルのデータ型を演算で処理する方法も
初めて知りました。実際の処理はたしかに別の形になりますが、このような処理をする場合は
クエリを使うものと考えていました。
Accessは使い始めて1年ぐらいで大変勉強になりました有難うございました。
今後ともよろしくお願いいたします。
hiroton様 有難うございます。読ませていただきました。
やはり半角カナは現状Access上で運用することは難しいようですね。。
納得いたしました。
連結フォームでき処理だと思いますので、わざわざ別にレコードセットを開かなくても、すでにレコードセットが開いています。
単純に Me!フィールド名でカレントレコードのデータにアクセスできます。
下記のコードで済むことです。
提示の処理なら、フォームでやらなくても、テーブルの方で、「氏名」フィールドのデータ型を「演算」にしておいて、
式を
[名字] & [名前]
と設定すれば済む話でもあります。実際の処理ではないとは思いますが、式で表現できることならこちらの方法でもいいでしょう。
Microsoft BarCode Control 16.0の公式ドキュメントが見つかりませんね
いくつかのサイトによると完璧なものではないようです
Microsoft Access Barcode Control は使わないほうが良い(Qiita -@Umazularさん)
Access 2016でバーコード、QRコードを作成する(A-POCさん)
2バイト文字には対応していないらしいので、一部でも表示されたのがたまたま(バグ)なんでしょう
出力がおかしければリーダーを変えても結果は同じですね
「他社のアドオン」の仕様を確認してください。これは「他社」に確認を取るべきでしょう
hatena様
アドバイスありがとうございます。ご指摘の通りです。
半角カナ入力でテーブルに”アイウエオ”と書き込みしています。
そのテーブルをソースにしてレポートでActiveXコントロールの
「Microsoft BarCode Control 16.0」を選択⇒QRコードを作成しています。
レポートを印刷して作成したQRコードをバーコードリーダーで読み取ると
"アウオ"というような形で1文字飛ばして表示されます。
複数のリーダー・また他社のアドオンを使用してみても同じ状況が発生し、
原因がわからない状況でございます。
もう少し状況を詳細に説明すると回答がつくかも。
テーブルにあるデータをバーコードコントロールでレポート上に表示させた。
それをバーコードリーダーで読み込ませると、元のデータと異なっている。
というようなこと?
私は、バーコードリーダー使ったことないので、回答できませんが。
こうしてみたらどうでしょう?
※コードの善し悪しは評価していません
Excel処理の問題のようなので、この掲示板(ACCESS掲示板)よりもExcelに強い場所で質問するとうまく解決できるかもしれませんね
ありがとうございました。
教えていただいた方法でちゃんと表示されるようになりました。
基本を理解しないまま、本やネットを調べ調べ作っているのでいけませんね。
教えていただいた、正規化も調べてみました。
ちゃんと時間をとってしっかり学習していこうと思います。
ご丁寧に教えていただき、本当に助かりました。
ありがとうございました。
hatena様
ご教授ありがとうございます。
上手く表示させることが出来ました。
そのフォームは連結フォームですか、非連結フォームですか。
コントロールソースが空欄なら非連結フォーム、テーブル名、クエリ名が設定されていれば連結フォーム
連結フォームの場合は、レコードソースのフィールドに日時のフィールドがありますか。
あるなら、テキストボックスのコントロールソースを日時フィールドに設定します。
非連結フォームなら、まずはテーブルを作成して、日時のフィールドを追加して、
フォームのレコードソースとテキストボックスのコントロールソースを設定すればいいでしょう。
ちなみに、マクロの式は、下記でもOKです。
今後のことを考えると主キーの設定をした方がいいと思います。
データベースの機能を活かすには主キーの設定は必須と考えていいでしょう。
とりあえず現状でいくなら、
リストボックスの値集合ソースのクエリのSQLを下記のようにします。
コンボボックスの更新後処理のイベントプロシージャを下記のように記述します。
リストボックスの名前は「lst_内訳」と仮定したコードですのでその部分は実際の名前に変換してください。
とりあえずこれでうまくいくはずです。
ただし、
Accessはまがりなりにもデータベースですので、データベース設計の基本を理解せず設計をすすめると、あとで後悔することになります。
テーブル設計については「正規化」という原則があります。まずはこのあたりから学習されることをお勧めします。
コードを見ると、sqlから生成されたレコードセットをそのままシート上に出力するもののようですので、
CopyFromRecordsetメソッドを利用すると、1行のコードでできると思います。処理速度も高速です。
下記が参考になります。
お手数をおかけしていて申し訳ありません。色々ありがとうございます。
テーブルについてですが、T_分類も、T_内訳も、主キーの設定をしていませんでした。(必要でしょうか)
両テーブルとも、これ以外のフィールドはありません。
分類名は、同じものが格納されています。
どうぞご教授のほどよろしくお願いします。
お付き合いいただきありがとうございました。
処理が中断した後、F5を押すと、処理は続くので何が原因なのか判断できない状況です。
(一定数コピペが進むとまた止まります。)
あまり良い方法ではないと思いますが、DoEventsを挟んで一時的に対応したいと思います。
(DoEventsを挟むと最後まで処理は進みます。遅いですが。)
回答の前に、テーブル設計の確認ですが、
T_分類 (コード, 分類名) の主キーフィールドは「コード」になってますか。
T_内訳(分類名, 内訳)にはこれ以外のフィールドはないですか。また、主キーフィールドはありますか。
分類名 は T_分類 の 分類名 と同じものが格納されてますか。
その結果から判断するかぎりは、エラーがでるのは考えにくいですね。
ちょっとお役に立てそうにないです。
お返事ありがとうございます。
一応、調べてみました。 これで大丈夫でしょうか。
リストボックスの値集合ソースのクエリのSQL文(SQLビューで確認できます)
SELECT T_内訳.[分類], T_内訳.[内訳]
FROM T_内訳;
コンボボックスの下記の設定
値集合ソース T_分類
値集合タイプ テーブル/クエリ
連結列 2
列数 2
列幅 0cm;3cm
コンボボックスの更新後処理に設定したマクロまたはVBAコード
ここまで行きついていなくてまだ設定できていなかったです
必要かわからない情報ですが…
コンボボックス(cmb_分類)には、T_分類というテーブルの2列目(1列目:コード・2列目:分類名)を表示するようにしていました。
リストボックス(lst_内訳)には、T_内訳というテーブル(1列目:分類名・2列目:内訳)を表示したくて、Q_内訳を作りました。
コンボボックスの分類名と、T_内訳の分類名が一致した場合、リストボックスに該当する内訳を表示したいという感じです。
説明が下手で申し訳ありません。
よろしくお願いします。
下記の情報を提示してもらえますか。
リストボックスの値集合ソースのクエリのSQL文(SQLビューで確認できます)
コンボボックスの下記の設定
値集合ソース
値集合タイプ
連結列
列数
列幅
コンボボックスの更新後処理に設定したマクロまたはVBAコード
教えていただきありがとうございます。
色々試行錯誤していて、お返事が遅くなりました。
教えていただいた方法で進めていて、値集合ソースのテーブルをクエリにしました。
ですが、コンボボックスの値で抽出条件の設定がうまくできません…
無知で申し訳ありませんが、方法を教えていただけませんか。
必要な情報があれば明記します。
よろしくお願いします。
遅くなり申し訳ございません。
イミディエイトウィンドウに表示されたのは下記です。
AAAA-AAAAA-AAA
33
$A$33
リストボックスの値集合タイプは「テーブル/クエリ」ですか。
だとしたら、値集合ソースのテーブルをクエリにして、コンボボックスの値で抽出条件を設定します。
コンボボックスの更新後処理で、リストボックスを再クエリすればいいでしょう。
まずは、動作確認中(デバッグ中)は、エクセルを表示させて実行しましょう。
エラーが出て中断すると、非表示のエクセルの残ってしまいますので。非表示のエクセルはPCをシャットダウンしないかぎり、閉じるのが難しいので。
エラーが出る前の行に下記のようなデバッグ用のコードを挿入して実行してみてください。
これでエラーが出て中断したときのイミディエイトウィンドウに出力されたものをコピーしてもらえますか。
それで原因がわかるかもしれません。
情報不足で申し訳ございません。
コード全体は下記です。
エラーメッセージは下記の通りです。
実行時エラー'1004'
アプリケーション定義またはオブジェクト定義エラーです。