StrSQL = _
" SELECT TOP 1 基4, 変位4, №" & _
" FROM T_01_地耐力" & _
" WHERE (T_01_地耐力.№ Between 1 And 9)" & _
" ORDER BY T_01_地耐力.変位4 DESC , T_01_地耐力.№ DESC"
Set rs = CurrentDB.OpenRecordSet(StrSQL)
If rs![変位4] <> 9 Then
rs.Edit
rs![基4] = "※"
rs.UpDate
rs.Close
End If
お返事が遅くなり申し訳ありません。もう一度教えていただいた文章を読み直し、デバッグ用コードも使い書き直しまして無事に進めることができました。ありがとうございました。そのうえで追加質問をさせてください。
更新条件で[No]が1から9まで、[変位4]の値が一番大きいものに※マークを付けるだけではなく、でも一番大きい[変位4]の値が[No]が、9ではないものに限定したいです。通常のクエリなら2つ3つ重ねていけばできますがsqlでは、どのように追記すれば良いのでしょうか?おねがいいたします
'''" WHERE T_01地耐力.№ Between 1 And 9" &
" ORDER BY T_01_地耐力.変位" & A1 & " DESC , T_01_地耐力.№ DESC;"
'''
StrSQL = _
" SELECT TOP 1 基4, 変位4, №" & _
" FROM T_01_地耐力" & _
" WHERE (T_01_地耐力.№ Between 1 And 9)" & _
" ORDER BY T_01_地耐力.変位4 DESC , T_01_地耐力.№ DESC"
StrSQL =
"SELECT TOP 1 基4, 変位4, №" &
"FROM T_01地耐力" &
"WHERE (T_01地耐力.№ Between 1 And 9)" &
"ORDER BY T_01_地耐力.変位4 DESC , T_01_地耐力.№ DESC"
strSQL = "SELECT TOP " & i2 & Cd & " FROM " & Tn & " WHERE " & Sc & " ORDER BY 出勤データ.月日 DESC" '降順でi2番目までのデータを取得
strSQL = "SELECT TOP 1 * FROM (" & strSQL & ") ORDER BY 出勤データ.月日" '上記のデータから昇順で1番目のデータを取得(結局降順でi2番目のデータ)
主キーはデータベースのもの、顧客番号や売上番号、請求書番号などは人がみるもの、という感じでしょうか?
主キーを書類などに記載するものではないので、主キーは1からはじめた自動採番、先述の各番号は、例えば10001からはじめていく、といった具合でほぼ同じようなデータをつくるのが普通ですか?
伝票や請求書に書いてある伝票番号や顧客番号、請求書番号は主キーを書くことはないものでしょうか?
AutoFontSize関数自体にテキストの中央配置の機能があるのでそれを使えばどうでしょう。
AutoFontSize関数を垂直文字配置の指定ができるよう改良 - hatena chips
使用例
第3引数に Centerを指定すると中央配置になります。
縦書きのテキストボックスでも大丈夫です。
ハンドルネームを入力し忘れました。失礼。
@IT: システムの寿命はコードで決まる!
そのコードが「業務で利用するコード」であるかどうかによります。
それとは別の問題として、有意コードや「後から変更される可能性がある情報」を格納するためのフィールドをテーブルの主キー(個々のレコードを一意に識別するためのインデックス)として定義することは、できるだけ避けた方が良いでしょう。
顧客の名前(の頭文字)は、後から変更(改名、または誤って入力された情報の修正)される可能性があります。
同上。
そういう形でよいと思いますが、それと「[顧客番号]を有意コードとするべきか否か」はあくまで別の問題です。
例えば、もし顧客の名前(の頭文字)が変更されたら、わざわざ[顧客番号]も新たに発行し直したりするのでしょうか。
>それですと0001の顧客や新たな顧客に発行した番号が0015などだと、顧客が少ないと見られて不利になりそうな気もします
表示する必要がない。下記のように、わかりやすい形で表示する事にしたのではないのか?
わたしもさほど詳しくないので想像が多分に含まれる所感として記載してみます。
>データベースではコードに意味を持たせてはいけない
「コード」を「キー」として扱う場合、まずその内容は数値のみで構成されるのが良いのはご存知のとおりだと思います。
ただ「顧客番号」や「商品番号」とする場合、数値だけでは分かりにくいので、それは「キーとしてのコード」ではなく、「意味のある管理番号」として別途追加するのが良いだろう、ということではないでしょうか。
なので「00001、00002といったIDをリレーションにつかい、顧客番号は文字と同じ扱いにする」が問題になる理由がわかりません。これはなぜでしょうか。
あと「コード」(キー)に「顧客番号」として「CA001」とした場合、後から修正できません(キーは通常修正しないので)
ただ企業などで使用する場合なにがおこるかわかりませんので、修正ができない「コード」(キー)に意味を与えるべきではない、ということではないでしょうか。
>それですと0001の顧客や新たな顧客に発行した番号が0015などだと、顧客が少ないと見られて不利になりそうな気もします
これは単純に開始番号を「1234」とかにすればいいと思いますが。
つまり意味が発生するとそういった意味でも使いにくくなるということかなと思います。
そこに、IF式を入れるだけで、そんなに意味合いが変わるのですね!無事に出来上がりました。長々と本当に、本当にありがとうございました。
Hatenaさん、お世話になります。
テラテイルの質問が未クローズでしたが、修正依頼荒らしによる再三の嫌がらせのため、退会致しました。
アドバイス通り、コードを切り分けてデバッグを行っていたところ、原因に行き当たりました。
レポートデザイン上の社名テキストボックスのフォントサイズが15になっており、社名2か3にデータがない場合、
If文で社名1~3のフォントサイズを小さなものに揃えると15が採用されてしまい、結果社名1のテキストボックスの表示が小さくなってしまうようでした。
VBAで社名1~3に.FontSize = 22を設定すると、テキストボックスの大きさにあったフォントサイズに変更されるようになりました。
アドバイスありがとうございました😊
下記でどうでしょう。
返信ありがとうございます。「[No]が1から9まで」の範囲で[変位4]か一番大きいレコードの[No]が9の時は※マークをつけない ということです。可能でしょうか?お願いいたします。
抽出条件が、「[No]が1から9まで」かつ「[No]が、9ではないもの」ということでしょうか。
だとしたら、「[No]が1から8まで」ということになりますが、そういうことではないのですか。
ではなくて、
「[No]が1から9まで」の範囲で[変位4]か一番大きいレコードの[No]が9の時は※マークをつけない(更新しない)ということでしょうか。
フォントサイズが必要以上に小さくなってしまう
上記の質問の同じ人ですよね。
上記の質問の修正依頼の方にコメントしましたので、ご参照ください。
上記の質問のコードを見る限りは、AutoFontSizeの使い方を間違っているのだと思います。
お返事が遅くなり申し訳ありません。もう一度教えていただいた文章を読み直し、デバッグ用コードも使い書き直しまして無事に進めることができました。ありがとうございました。そのうえで追加質問をさせてください。
更新条件で[No]が1から9まで、[変位4]の値が一番大きいものに※マークを付けるだけではなく、でも一番大きい[変位4]の値が[No]が、9ではないものに限定したいです。通常のクエリなら2つ3つ重ねていけばできますがsqlでは、どのように追記すれば良いのでしょうか?おねがいいたします
'''" WHERE T_01地耐力.№ Between 1 And 9" &
" ORDER BY T_01_地耐力.変位" & A1 & " DESC , T_01_地耐力.№ DESC;"
'''
おはようございます
返信ありがとうございます
まさにそれでした!フィルターでした
1日謎に振り回されていたので助かりました
解決しました
ありがとうございます!!
この時レコード数はいくつありますか?
1つならフィルターが、複数あるならレコードの移動(+検索?)が実行されています
me.requery
だけで動いているならフィルターだと思いますがフィルターを保存する
Accessフォームでフィルターを使って特定のレコードのみ表示する方法(工場エンジニアのAccessスキルさん)
フィルターを動的に設定する場合はよくVBAを使いますが、たいていは「フォームのプロパティを変更する」として実装されます。なので、そもそもフォームそのものに保存できるようなフィルターであれば、わざわざVBAで記述する必要はなく、読みこみなおし(
me.requery
)だけでフィルターを適用することができます既にhirotonさんの回答で解決できると思いますが、
VBAで生成したSQL文の確認方法をアドバイスしておきます。
下記のようにデバッグ用コードを挿入します。
これを実行するとイミディエイトウィンドウに、StrSQLに格納されている文字列が出力されますので、
それをコピーしてクエリのSQLビューに貼り付けます。
そしてこのクエリを開くことができれば、正しいSQL文が生成できているということです。
上記の場合だと、開くことができないはずです。
SQL文をよく見れば、区切りが適切にできていないのが分かります。
hirotonさんの回答のコードなら問題なく実行できるでしょう。
動作確認後はデバッグ用コードは不要なので削除しておいてください。
前回の質問でも同じ補足をしましたが、VBAの文字列では改行をそのまま入力することはできません
「
_
」はVBAコードとしての改行を無視するのみですは、単に
として実行されます。この結果生成される文字列は
SELECT TOP 1 基4, 変位4, №FROM T_01_地耐力
となります。これでは、「
SELECT
句で№FROM
フィールドを指定」という記述になってしまいますねこの直後ですでに構文エラーとなるような気もしますが、エラーメッセージがそのように出力されるのはよくわかりません
hirotonが提示したちょっと楽をする記述をするなら次の通りです
StrSQL =
" SELECT TOP 1 基4, 変位4, №" &
" FROM T_01地耐力" &
" WHERE (T_01地耐力.№ Between 1 And 9)" &
" ORDER BY T_01_地耐力.変位4 DESC , T_01_地耐力.№ DESC"
実際のSQL構文部分の各行で先頭に半角スペースを追加する形で記述します
SQL構文は「改行」と「半角スペース」が同じ役割をするので、VBAでは直接入力できない改行の代わりに半角スペースを使います。さらに、改行を行の最後に入力するかわりに、行の先頭で記述します
こうすることにより、
面倒な改行の入力が半角スペース1つで済む
インデントがそろって見やすい
行末(文字列の最後)という気づきにくいところでの記述漏れを防げる
というメリットがあります
何度も申し訳ありません
記載方法のご説明、ありがとうございました。今度はちゃんと見えていますでしょうか?
クエリのデザインビューに変数に置き換える前の以下の分を張り付け、& _ と " を外して実行させてみました。
クエリの画面では、表示されました。もう一度VBAに戻って & _ と " を付け実行すると
今度は実行時エラー3075「WHERE № Between 1 And 9 ORDER BY T_01_地耐力.変位4 DESC , T_01_地耐力.№ DESC」
演算子がありません になってしまいました。
お願いいたします
そうでしたか。
この掲示板はマークダウン記法が使えますので、コードを掲載する場合、コードブロック内に記述すると、いいでしょう。
下記で使い方はを解説してますので、ご参考に。
StrSQLのSQL文が間違っているということですね。そのSQL文をクエリにデザインビューに貼り付けて開くことができるか確認してみてください。
すみません。各構文に &_ に追加してコピーして、こちらに張り付けたのですが消えてしまっているようです。
実際のVBAには付いています。理解できているでしょうか?
フィールドを文字列で参照する方法、ありがとうございました。早速変更いたしました。
今度は Set rs = CurrentDb.OpenRecordset(StrSQL) のところで
実行時エラー3061 パラメータが少なすぎます。1をしてください になってしまいました。お願いたします
上のコードを実行してみたのですが
rs. "[基" & A1 & "]='※'"
のところで 構文エラー になってしまいました。 お願いいたします
考え方はそれであってますが、そのコードではコンパイルエラーで実行できませんね。
前回の質問の内容を理解して書き直す必要があります。
あと、フィールドを文字列で参照する場合は、下記のような感じでFieldsプロパティを使います。
ありがとうございます。VBAで直接更新ができるのですね。勉強不足ですみません。
では変数にしたいのなら以下のように変更すれば良いのでしょうか?
for A1=1 to 4
StrSQL1 =
" SELECT TOP 1 基" & A1 & ", 変位" & A1 & ", №" &
" FROM T_01地耐力" &
" WHERE T01地耐力.№ Between 1 And 9" &
" ORDER BY T_01_地耐力.変位" & A1 & "DESC , T_01_地耐力.№ DESC;"
Set rs = CurrentDB.OpenRecordSet(StrSQL)
rs.Edit
rs!"[基" & A1 &"] = '※'"
rs.UpDa[te
rs.Close
next
更新したいテーブルは、T_01地耐力 ですか。
T_01地耐力 を特定の抽出条件で抽出して指定のフィールドで並べ替えて、先頭のレコードの[基4]フィールドを更新したいということですか。
だとしたら、VBAを使うなら、更新クエリではなく、VBAで更新した方が簡単そうです。
とりあえず考え方だけのコード例。
説明不足ですみません。更新クエリ一発で解決できてしまうのでしたら、ぜひともお願いいたします。本当にやりたいことはVBAで基4, 変位4, の「4」を変数にして、for next 1~4 で実行したいのです。通常のクエリ処理しか行ったことがないので、選択クエリを作成し、その結果で更新クエリを実行する。という流れしか知らなかったです。変数に置き換える前に、固定の名前ままでSQLを見たほうが理解できると思いまして、今回と前回に質問を分けました。お願いいたします
提示のコードは構文エラーで実行できないものですが、実際のものは、前回の質問で正しいものに修正はできているということでよろしいですか。
更新クエリ一発でやりたいということですか。
VBAでSQLを記述しているということは、VBAを使ってもいいということですか。
VBAは基本的に1行1命令、そこから分かっていませんでした。「& _」の意味も...
とっても分かりやすくて助かりました。本で見ても検索しても理解できなくて。クエリのSQLを張り付けて削除したり付け加えたり、深みにハマっておりました。ありがとうございました。
行連結文字
VBAは基本的に1行1命令です
行を続けて1命令とする場合には
_
([スペース]+[アンダースコア])を最後の行を除いた各行の行末に記述しますStrSQL = "SELECT TOP 1 基4, 変位4, №" & _
"FROM T_01_地耐力"
"WHERE T_01地耐力.№ Between 1 And 9" &
"ORDER BY T_01_地耐力.変位4 DESC , T_01_地耐力.№ DESC;"
質問のコードでは1行目に続けて2行目までは1命令として処理されますが、3行目・4行目はそれぞれ独立した1命令と処理されるため不正なコードとしてコンパイルエラーになります
ついでにですが、そのまま質問のコードのような連結を行うとクエリとして実行できないSQL文になります
そのままVBAで連結された場合
SELECT TOP 1 基4, 変位4, №FROM T_01_地耐力WHERE T_01地耐力.№ Between 1 And 9ORDER BY T_01_地耐力.変位4 DESC , T_01_地耐力.№ DESC;
となります。VBAでは文字列に改行をそのまま入力することはできません
のように、改行を含んだ文字列とするためには改行を入れる部分に代替のコードを記述する必要があります。たとえば
vbNewLine
を使いますhirotonがSQL文をVBAで作る場合は簡単なものであれば次のような記述にしたりします
・1行目は代入する文字を記述せず、
_
で即座に終えます・2行目のSQLの開始行にも先頭に空白スペースを入れます
・改行コードは使いません
これで、目的のSQL文をそっくりそのまま使いつつ、VBA記述のルールから逸脱せず、ミスしにくい記述ができます
いまさらですが、環境が試せた(windows 11, Microsoft 365)のでやってみたら、たしかに表示できませんでした。
htmlなら表示できたので、webbrowserコントロール=IE、IEはEdgeにリダイレクト、Edgeでmhtを開く時は~なあたりでこけてしまうんですかね
Edgeを扱うコントロールとしてwebview2というコントロールがあるようなので、これに置き換えていく形でしょうか
お騒がせいたしました。落ち着いてみたら解決できる事でしたね。すみません。ありがとうございました。
後半の方を見てませんでした。下記でどうでしょうか。テーブル名の部分は実在のテーブル名にしてください。
実際 教えていただいたものを張り付けて実行したのですが
実行エラー3075 DMax(変位],№>=1 AND №<=9) AND ([№] Between 1 And 9) と表示されました。
何がいけなかったのでしょう?お願いいたします
ありがとうございます。途方に暮れていたのでとっても助かります!
上記コードの改行は実際にはないとして(あると構文エラーで実行すらできないので)、
下記に変更するといいでしょう。
VBAの文字列内(""内)で"を表現するには""と重ねる必要があります。
あるいは、'を使う方が読みやすいですね。
adoCn.Execute strSQL
を
daoCn.Execute strSQL
に変えるだけで良かったのですね。
strSQL = "SELECT TOP " & i2 & Cd & " FROM " & Tn & " WHERE " & Sc & " ORDER BY 出勤データ.月日 DESC" '降順でi2番目までのデータを取得
strSQL = "SELECT TOP 1 * FROM (" & strSQL & ") ORDER BY 出勤データ.月日" '上記のデータから昇順で1番目のデータを取得(結局降順でi2番目のデータ)
にした方が、並べ替えるだけなので、早いと思います。
色々と、有難うございました。
もしかして、If i = 2 Thenは、If i = i2 then の打ち間違えかしら。念の為、追記しておきます。
既に言われていることですが、用語の使い方が間違っているので質問の意図が正しく伝わってきません。「ADO」や「DAO」も、ところどころ、逆の用語ではないか?と思うところがあります
質問を投稿する前によく読みなおして、正しい質問になるようにしてください
DAOにもクエリ(SQL構文)をそのまま実行するメソッドが存在します。メソッド名もADOと同じ
Execute
ですDatabase.Execute メソッド (DAO)
QueryDef.Execute メソッド (DAO)
Connection.Execute メソッド (DAO)
参考:保存済みクエリーを使うか、VBAでSQL文を直接発行するか?(T'sWareさん)
単純なSQL構文であれば
だけで動作します
すみません。
DAOの存在を2日ほど前に知ったばかりで、コードの書き方も手探りの状態で、いっぱいいっぱいの状態で失礼なやり取りになっております。
daoRs.Editって、宣言が必要なんかい
そもそも、Editを.の後ろに付けて命令するのか
のレベルで、身動きが取れない状態です。
ただ、処理速度は抜群に早いです。
前回教えていただいた、ADOでサブクエリを使うコードのADO版ということだと思いますので、
サブクエリを使うときに利用させていただきます。
deleteを調べたら、
delete文は、該当する行をまるごと削除する用途で使われるSQL文です。一方で、特定のフィールドだけを削除することはできません。例えば「該当する行のうち、一部の列に格納されたデータだけを削除したい」といった用途では使えません。
delete文は行の削除には使える一方で、列を削る用途には使えません。この操作は、ALTER TABLE文に「DROP COLUMN (削除する列名)」をつけることで行なえます。
ということがく分かりました。
Nullに置き換えなければなりませんでした。
危なかったです。
Nullへの書き換えですが、
ADOでは、
strSQL = UPDATE 出勤データ SET 出勤データ.番号 = Null;
adoCn.Execute strSQL, lRecordAffected
で、一括処理できているようなのですが
DAOのコードは、4時間近くかけてLoopさせる方法から前進しません。
hatenaさんが言うとおり、たいていは同じ処理ができるはずだと思うのですが。
お手数かけますが、アドバイスお願いいたします。
これに関しては、どのような一括処理なのか言及されてませんので、
無理とも可能とも判断のしようがありません。
連番を振りたいということに関してなら、更新クエリで一括でする方法はあります。
全レコードの番号フィールドをNullにしたいなら、更新クエリで一発です。
個人的な意見です。MsAccessは、流行り廃れの成長期を過ぎて、こういうもんだよねと結論が出ています。たぶん検索すればLoopで1件ずつ処理がヒットするはずなので、そういうもんだと見切りをつけます。もしかすると、一括処理する機能が公式リファレンスのどこかに埋もれているかもしれませんが、もっと将来性がある開発基盤に期待したほうが有意義です。
個人的には、1度番号(検索用)を付けたら変更しません。番号(表示順)であれば、動的に変わるのかしら、という設計をちらほら見かけたことはありますが、ちょっとすぐに例示できません。
>No4
これは、あるあるなので共感します。主にコーディングで活動されているのかな、と思いながら回答してみましたが、なかなか大変です。