strSQL = "SELECT * FROM テーブル1 WHERE 地域 IN(SELECT 地域 FROM テーブル1 WHERE (ID = 1 And 収入 >= 100) Or (ID = 2 And 収入 >= 60) Or (ID = 3 And 収入 >= 20) GROUP BY 地域 HAVING Count(1) = 3);"
Sub main()
Dim strSQL As String
addLine strSQL, "SELECT * FROM テーブル1 WHERE 地域 IN(SELECT 地域 FROM テーブル1"
addLine strSQL, "WHERE (ID = 1 And 収入 >= 100)"
addLine strSQL, "Or (ID = 2 And 収入 >= 60)"
addLine strSQL, "Or (ID = 3 And 収入 >= 20)"
addLine strSQL, "GROUP BY 地域"
addLine strSQL, "HAVING Count(1) = 3"
addLine strSQL, ");"
MsgBox strSQL
End Sub
Sub addLine(str As String, addStr As String)
str = str & vbNewLine & addStr
End Sub
=IIf([cboTD01] Like "※*" And [cboTD02] Like "※*" And [cboTD03] Like "※*" And [cboTD04] Like "※*" And(IsDate([txtTD05]) Or [chkTD05]) And (IsDate([txtTD06]) Or [chkTD06]) And (IsDate([txtTD07]) Or [chkTD07]) And (IsDate([txtTD08]) Or [chkTD08]) And ([cboTD09] Like "※*" Or [chkTD09]) And ([cboTD10] Like "※*" Or [chkTD10]) And ([cboTD11] Like "※*" Or [chkTD11]) And ([cboTD12] Like "※*" Or [chkTD12]) And ([cboTD13] Like "※*" Or [chkTD13]) And ([cboTD14] Like "※*" Or [chkTD14]) And (IsDate([txtTD15]) Or [chkTD15],"済","")
=IIf([cboTD01] Like "※" And [cboTD02] Like "※" And [cboTD03] Like "※" And [cboTD04] Like "※" And(IsDate([txtTD05]) Or [chkTD05]) And (IsDate([txtTD06]) Or [chkTD06]) And (IsDate([txtTD07]) Or [chkTD07]) And (IsDate([txtTD08]) Or [chkTD08]) And ([cboTD09] Like "※" Or [chkTD09]) And ([cboTD10] Like "※" Or [chkTD10]) And ([cboTD11] Like "※" Or [chkTD11]) And ([cboTD12] Like "※" Or [chkTD12]) And ([cboTD13] Like "※" Or [chkTD13]) And ([cboTD14] Like "※" Or [chkTD14]) And (IsDate([txtTD15]) Or [chkTD15],"済","")
Dim strSQL As String
strSQL = "SELECT * FROM テーブル1 WHERE 地域 IN(SELECT 地域 FROM テーブル1"
WHERE (ID = 1 And 収入 >= 100)
Or (ID = 2 And 収入 >= 60) _
Or (ID = 3 And 収入 >= 20)
GROUP BY 地域
HAVING Count(1) = 3
);"
Function VERCHECK()
Dim DB1 As DAO.Database
Dim DB2 As DAO.Database
Dim RS1 As DAO.Recordset
Dim RS2 As DAO.Recordset
Dim strAPPT As String
Dim strDBPT As String
DoCmd.OpenForm "F_起動"
Set DB1 = DBEngine.Workspaces(0).OpenDatabase("共有サーバの◯◯.mdb")
Set RS1 = DB1.OpenRecordset("T_VERINFO")
Set DB2 = DBEngine.Workspaces(0).OpenDatabase("C:各pc用の◯◯.mdb")
Set RS2 = DB2.OpenRecordset("T_VERINFO")
If RS1("Ver") > RS2("Ver") Then
If MsgBox("新しいバージョンがあります。アップデートしますか。", vbYesNo) = vbYes Then
RS1.Close
RS2.Close
DB1.Close
DB2.Close
Set RS1 = Nothing
Set RS2 = Nothing
Set DB1 = Nothing
Set DB2 = Nothing
FileCopy "共有サーバの◯◯.mdb", "C:\各pc用の◯◯.mdb"
End If
End If
strAPPT = SysCmd(acSysCmdAccessDir) & "\MSACCESS.EXE"
strDBPT = "C:\各pc用の◯◯.mdb"
Shell strAPPT & " " & strDBPT, vbNormalFocus
Application.Quit
End Function
Shell strAPPT & " " & strDBPT, vbNormalFocus
Application.Quit
End Function
DCount関数は下記のような構文になります。
DCount(フィールド名, テーブル名またはクエリ名, 抽出条件)
また、それぞれの引数は文字列で指定します。
DCount 関数 - Access
案件番号フィールドが数値型なら、下記のコードになります。
案件番号フィールドがテキスト型なら、下記のコードになります。
回答はお二人提示されている通りですので、基本的なところをすこし
自分の載せたリンクは回答の裏付けのためで、そこで勉強してほしいという意図はほぼありません。質問の要点も分からない状態だったし
最初に記載した通りですが、VBAでは改行(Enterキーを押して入力される画面に見えないモノ)は特別な意味を持ちます。文字列はダブルクオーテーション(「
"
」)で囲みましょうというルールがありますが、この改行を超えて「改行を改行文字として文字列に含めること」はできません。ではどうするかというと、今回のようにSQLとして扱う文字列であれば、改行は別に改行でなくともいいので半角スペースに置き換えてVBAの命令文1行で済ませてしまうというのが一番単純です。
最初のhatenaさんの回答(>> 1)の通りですね。
では、テキストとして改行を入れたい場合どうしたらいいかというと、改行として認識される文字コードを埋め込むという手法をとります。具体的にはkitasueさんが提示されている通り、vbNewLineをテキストの改行したい場所に文字列として連結してあげればいいです。文字列を連結する場合はお互いを「 & 」で繋げます。
最初の1行の表示からそうですが長いですね。こうなってくるとVBAコード上の見栄えの問題からコード上で改行を使ってどうにかできないかと考えることになります。
ちなみに、個人的にはアンダースコアを使った方法はいろいろと厄介なのでオススメしません。
ついでにたまに自分がやる手法でも
前にACCESS本体をバージョンアップしたらなんかおかしくなったってのを見たことがありますが、セクション最下部に置いた改ページコントロールの下に隙間ができるようになったってのがありました。
2ページ目以降なぜか最上部にわずかな隙間ができて、ページごとの合計がどうも1行分ずれているらしいというのでいろいろ見ていたら前のページの最終行が次のページの先頭の行として重複するようになったって感じでした
今回の例題はセクションの最上部に改ページがあるタイプなので同様の問題が起こることはなさそうですが、行単位で制御したいなら改ページコントロールを使うことにいいことはなさそうですね
なるほど!余計な遠回りをしてしまっていました…根本的なことに気づけずお手数をおかけしてすみません…
フォームのレコードソースをクエリにして、コンボボックスの値集合ソースのテーブルを追加します。
テーブルを適切に結合して、追加したいテーブルから表示したいフィールドを表示させるようにします。
これで、フォーム上のテキストボックスのコントロールソースで表示したいフィールドを選択することができるようなります。さらにテキストボックスの「編集ロック」を「はい」にして編集できないようにします。そうしないとマスターのデータが編集出来てしまい具合がわるいので。
現状のクエリのSQLを提示してもらえますか。
まずは、文章で状況を説明してください。
1.については、
コントロールソースにどのような式を設定したのか。
2. については、現状のVBAコードを提示してください。
また、どのようにうまく動作しないのか具体的に説明してください。
エラーがでるとか、反応がないのとか、・・・
左端の列の、
1, 2, 3, 4, 5
のフィールド名を仮にSEQとすると、(グループ化した上で)SEQの最小でソートすれば良いのでは。
あるいは、
とか。
Dim strSQL As String
strSQL = ""
strSQL = strSQL & "SELECT * FROM テーブル1 WHERE 地域 IN(SELECT 地域 FROM テーブル1" & vbNewLine
strSQL = strSQL & "WHERE (ID = 1 And 収入 >= 100)" & vbNewLine
strSQL = strSQL & "Or (ID = 2 And 収入 >= 60)" & vbNewLine
strSQL = strSQL & "Or (ID = 3 And 収入 >= 20)" & vbNewLine
strSQL = strSQL & "GROUP BY 地域" & vbNewLine
strSQL = strSQL & "HAVING Count(1) = 3" & vbNewLine
strSQL = strSQL & ");"
でいかがでしょうか。
hirotonさんの提示したリンク先にも方法が解説してありますが、
方法: コード内でステートメントを分割および連結する - Visual Basic
分かりにくい場合は、下記も参考にしてみてください。
ソースコードが長い時に途中で改行する方法[エクセルVBA]
返信遅くなりました。
VBAの文字のコードが赤くなり、正しく記載できていない状態です。
この ")"の記載方法がわからなくて困っています。
記載いただいたURL参考にしてみます
追加クエリでは1レコードずつチェックしてメッセージを出してユーザーに選択されるというのは難しいですね。
とりあえず追加クエリで追加してしまってから、重複があったら、重複データを抽出表示して、そのデータをみて必要か不要かをユーザーに判断させて、不要なら、不要な方を削除させる、というようなユーザーインターフェイスがいいのではないでしょうか。
hiritonさんの提案されている重複を判断するルールを明確に決めることかできるならそれをシステムに組み込んだほうがいいでしょう。
そのうえで厳密にルールだけでは決められない、人間の判断が必要という場合は、上記の方法を採用するということになるかと思います。
うまく伝わっていないとアレなので
このようなユーザーの判断が挟まる処理は減らしたほうが楽ができますよという話です
例えば、「特殊案件として案件番号がすでに登録されていたらメッセージを表示して~」というのが質問時点での想定だと思いますが、
「案件番号」と「発送番号」を同時に重複チェックして、全く同じデータがあれば追加不可、「案件番号」に重複があっても「発送番号」が異なっていれば追加する
というような、重複とみなさないルール(=重複としてはじくルール)、つまり、確認メッセージを出したときにユーザーが「はい」と選ぶ基準をそのままシステムに実装しましょうということです。
あまり質問の内容に即した回答でもないので「やりたいこと」はそのままやりたいことリストにしておいてもいいと思いますよ
多分やりたいことがいっぱいあって(連番の扱いとか)全部の内容に一発で決まるような回答も難しいと思うので問題点を整理して番号を振ってみるといいと思います。回答側もどの部分についてなのか指摘しやすいので
そうですね…増やしたい理由もあったのですが、
その方向で考え直してみようかなという気もしてきました。
初心者ながら、設計について周りに相談できる相手がいないので、お言葉いただけてありがたいです。
個人的な意見ですが、複数フィールドをチェックするようにして、しっかりと重複データは登録しないシステムにしたほうがいいんじゃないかなぁと
簡易チェックで処理の分岐をユーザーに求めて作業が止まるのも、処理の選択に対する人為的なミスを考えるのもいまいちな気がするので
連番についてはオートナンバーのようなキーがあるなら必要になってから作ればいいので質問のような追加クエリを実行する段階ではいらないと思います
すみません!今アクセスを立ち上げなおしてコピーしなおしたら「長すぎる」とのエラーが出ず、どうも反映されたようです。原因は不明ですが、とりあえずうまくいきました。お手数をおかけいたしました。正規の件につきましては、なにかありましたらご助言いただけると助かります。
ありがとうございました。
現在のところ、特殊案件番号はオートナンバーにしています。
また、T_案件の主キーは案件番号です。
基本的には1つの案件番号に1つの特殊案件番号となる場合が多いのですが、稀に1つの案件番号の中に複数の情報が含まれており、特殊案件テーブルではそこをバラバラにしたい…というイメージです。
ただ、すでに特殊案件にコピーしているのに間違って2回目でコピーするのは防ぎたいため「既に存在しています。本当に追加してよいですか?」とのメッセージを出したく思っています。
T_特殊案件では、主キーを「案件番号+案件番号が存在する数の連番」みたいな形にしたいです。
今のところVBAは使っておりません。現在、帳票のフォーム(F_案件)で、任意の案件のボタンを押すと、
マクロ実行「クエリを開く」(Q_特殊案件追加という名前の追加クエリが実行される)して、
F_特殊案件に任意の案件データが追加される
という仕組のみとなっております。
追加するデータ(T_案件)は、外部からインポートしたデータ(複数レコード)です。今のところリンクはしていません。
(将来的にはリンクするかも。現在まだ設計中なのでリンクにすると修正が面倒だったのでまだしていません)
●追加先テーブルについて
テーブル名:T_特殊案件
フィールド名:案件番号、顧客番号、発送番号、フォルダパス
主キー:特殊案件番号
以上です。
ご確認ありがとうございます。すみません。最後の「)」抜けの件は、投稿したあと気づきました…
仰る通り、式が長すぎるようでエラーが出ます。正規化は考えているつもりなのですが…
ちなみにTDというのはTODOのことで、1つの案件に15個のTODOが存在しており、それらがすべて終わったら「済」が表示されるようにするための式になります。15個すべて1つずつの案件に紐づいているTODOなので、これ以上テーブルは分割できないかと思ったのですが、何か方法がありますでしょうか。。
提示の式の場合は、閉じカッコがひとつ少ないです。
,"済"
の前に閉じカッコが必要。ただし、
コントロールソースに設定できる式の長さには制限があったと思います。
また、このような長い式になるということは、テーブルの設計がまずい可能性が高いです。
「テーブルの正規化」ができているかをまずは確認すべきですね。
マークダウンのコードブロックに入れると * は消えません。
詳細は下記を参照してください。
Microsoft Access 掲示板 の使い方 Microsoft Access 掲示板 - zawazawa
下記のようになります。
「※」のあとには「*」があります。なぜかきえているようです。すみません。
ごちゃついた式ですみません。少しずつトライ&エラーで試しているところで、この式の半分程度で行き詰っていますが、全文作って載せました。
以下になります。連結フォーム、帳票フォームになります。
=IIf([cboTD01] Like "※" And [cboTD02] Like "※" And [cboTD03] Like "※" And [cboTD04] Like "※" And(IsDate([txtTD05]) Or [chkTD05]) And (IsDate([txtTD06]) Or [chkTD06]) And (IsDate([txtTD07]) Or [chkTD07]) And (IsDate([txtTD08]) Or [chkTD08]) And ([cboTD09] Like "※" Or [chkTD09]) And ([cboTD10] Like "※" Or [chkTD10]) And ([cboTD11] Like "※" Or [chkTD11]) And ([cboTD12] Like "※" Or [chkTD12]) And ([cboTD13] Like "※" Or [chkTD13]) And ([cboTD14] Like "※" Or [chkTD14]) And (IsDate([txtTD15]) Or [chkTD15],"済","")
実際のうまくいかない式を提示してもらえますか。(長くてもいいので)
あと、そのフォームは連結フォームですか、非連結フォームですか。
連結フォームの場合は、単票フォームですか、帳票フォームですか。
式ですが、実際は「済」のあとに「*」を使っています。関係ないと思いましたが一応修正したものを載せます。
=IIf((IsDate([テキストボックス1]) Or [チェックボックス1]) AND (([コンボボックス2] Like "済*") Or [チェックボックス2]),"完了","")
こんにちは。この件ですが、どうもうまくいきません。式にエラーが出て、修正(一度消して打ち直す)すると見た目全く何も変化していないのにうまくいったり、同じことを何度も繰り返しています。時々「式が長すぎます」というようなエラーも出ます。実際すごく式が長いので、トライアンドエラーにすごく時間がかかっています。クエリのデザインビューで設定することはできますでしょうか。具体的には下記のような式が、長いものになります。(そもそも式が間違っているのでしょうか…)
=IIf((IsDate([テキストボックス1]) Or [チェックボックス1]) AND (([コンボボックス2] Like "済") Or [チェックボックス2]),"完了","")
テキストボックス1かチェックボックス1がTRUEで、コンボボックス2かチェックボックス2がTRUEなら完了、といった式が15個程度続いている
それでやってみて「どううまくいかない」んですか?
そっくりそのままやろうとするとコードに記述した時点でエラーメッセージが出ると思いますが
VBAは基本1行1命令の言語で、改行は命令の終わりという特別な文字です。SQLのようにただの文字の区切りというわけではないので、改行を消して1行で記述するか、それなりの対処が必要です
方法: コード内でステートメントを分割および連結する (Visual Basic)
hatena様
遅くなりました。
Dim strSQL As String
strSQL = "SELECT * FROM テーブル1 WHERE 地域 IN(SELECT 地域 FROM テーブル1"
WHERE (ID = 1 And 収入 >= 100)
Or (ID = 2 And 収入 >= 60) _
Or (ID = 3 And 収入 >= 20)
GROUP BY 地域
HAVING Count(1) = 3
);"
自分なりに調べましたが、ここまでが限界でした。
申し訳ありません。
こんばんは。
本日Windows10でのテストが無事終了しました。
VBSで起動する事ばかり考えていたので、mdbでの起動を教えて頂き、大変助かりました。
ありがとうございました🙇♂️
起動のコードも載せておきます。
かなり独学で書いていますので、もっとスマートな書き方があれば、お時間ある時にご教授頂けると幸いです。
本当にありがとうございました。
ごめんなさい、お返事確認する前に新しく投稿してしまいました。ごちゃついてしまいましたが、ご教示いただいた内容で確認します。ありがとうございます。
あ、上記はインポートの定義修正ではなく、新しく定義を保存するということですね。すみません。それならエクセルファイルでも同じですね。承知しました。ありがとうございました。
エクセルファイルだとインポート定義は使えませんね。
インポート先のテーブルを先に作っておいて、そこにインポートするとどうでしょうか。私は試したことがないですが、試してみてください。
エクセルファイルをインポートではなくリンクにしておいて、そのリンクテーブルから追加クエリを作成してインポート先のテーブルに追加するという方法を私なら使います。これだと、クエリのデザインビューで好きなように変更できますので。
ご教示ありがとうございます。すみません、インポートについて詳しく記載しておりませんでした。エクセルファイルでのインポートなのですが、修正は難しいでしょうか。難しいようであれば、新たにテキストファイルのインポートを作成してみようと思います。
とりあえず現状のできているところまでいいのでVBAを提示してもらえますか。
あと、情報が不足しているので、下記の点についても補足してください。
例えば、
非連結フォームのテキストボックスに入力してある(1レコード)
別テーブルにあるデータ(複数レコード)
外部からインポートまたはリンクしたでータ(複数レコード)
テキストファイルのインポートでしょうか。もしそうなら、下記の手順で。
最初にインポートするときに、インポート定義で不要なフィールドをスキップするように設定しておいて保存しておきます。
Accessで保存したインポートの定義の利用方法 | できるネット
インポートを実行して、ウィザードの最後で [インポート操作の保存] にチェックをいれてから終了します。
インポートやエクスポートの操作の詳細を定義として保存する - Access
これで、次回から保存したインポート操作を実行すると定義した通りにインポートされます。
hirotonさん
ありがとうございます。ほぼ疑問は解消出来たと思います。
色々とコードまで例示くださり、大変分かり易かったです。
初期値のところは知識の整理になりました。
標準モジュールでの変数宣言とフォーム上のコントロールの値の設定は、初期値を明示的に設定しなかった場合ルールが異なるということですね。
hatenaさん
こちらの掲示板をご案内いただきありがとうございました。
Access、AccessVBAはほぼ初心者に近いのでまた質問させていただく機会があるかと思います。その時はまたよろしくお願いいたします。
ありがとうございました。
やはりそうですか・・・
別の方法を検討してみます。
ありがとうございました。
新規追加なら、新規行のレコードセレクタをクリックして新規行を選択してから、貼り付ければ、可能ですね。
ただ、エクセルのようにアンドゥが効かないので、変なところを選択して上書きしてしまうと取り返しがつかないのて、通常の運用で使うのはお勧めできないですね。
下記の方法でクリップボードのデータを取得できますので、それを使ってVBAでデータを追加する機能を実装するのがいいでしょう。
クリップボードとデータのやりとりをする:Excel VBA|即効テクニック|Excel VBAを学ぶならmoug
コントロールソースの式に関してADOはまったく関係ないです。
ワイルドカードは普通にLike 演算子 - Access
上記で紹介されているワイルドカードは使えます。(Access内のコントロールソースやクエリでは * だが、ADOでは % になるというだけのことです。)
式がまちがっているのでしょう。