• ベストアンサー

テキスト形式だけど「between a and b」を使うには?

AccessのVBAで検索するためのコードを作成しています。 とあるフィールドは形式が「テキスト形式」なんですが、 その中で「AからBの間」という検索をしたいんです。 くんでみたコードはこんな感じです。 condData = "(T_テーブル.Data between #" & Me!A.Value & "# and #" & Me!B.Value & "#)" WhereCond = WhereCond & "and" & condData WhereCond = Mid(WhereCond, strCount + 1) DoCmd.OpenForm "F_検索結果", acNormal, , WhereCond ですが実行すると、 実行時エラー'3075': クエリ式 'and(T_テーブル.Data between # A # and # B # )' の構文エラー:演算子がありません。 とでてしまいました。 どこがダメなのでしょうか? よろしくお願いします。

質問者が選んだベストアンサー

  • ベストアンサー
  • Gin_F
  • ベストアンサー率63% (286/453)
回答No.10

> とのことですが「抜き出す」とはどのようなことでしょうか? > xxx.xxxx.xxx.xxx > ~~~~~~~~ やり方としては、この部分を抜き出して、数値型で比較するか、 インデントができないので、ちょっとわかりにくくなったですね (^^ゞ 10文字目以降を取得するという意味です。

その他の回答 (9)

  • Gin_F
  • ベストアンサー率63% (286/453)
回答No.9

> ですので、「9文字目より右側」という固定条件で大丈夫です。 xxx.xxxx.xxx.xxx このような形式ということですか? で、最後の部分は桁数が固定じゃないんですよね? 並べ替えを例にすると分かりやすいのですが、テキスト型では 111.1 111.121 111.11 といったように並びます。 範囲検索する場合にも、上記の規則が適用されます。 なので、数値に変換した方がやりやすいのですが、そうなるとドットがあるため 単純に数値にすると、小数点と認識されます。 xxx.xxxx.xxx.xxx ~~~~~~~~ やり方としては、この部分を抜き出して、数値型で比較するか、 抜き出した後、桁数を揃えて、テキスト型で比較するか。ですね。

w-inty
質問者

お礼

回答ありがとうございます。 >この部分を抜き出して、数値型で比較するか、 >抜き出した後、桁数を揃えて、テキスト型で比較す るか。 とのことですが「抜き出す」とはどのようなことでしょうか?

  • Gin_F
  • ベストアンサー率63% (286/453)
回答No.8

> 何かおかしなところはありますでしょうか? > 一番右の「.」ではなく、右から2番目の「.」の位置を抽出するにはどのようにしたらいいのでしょうか? 仕様が変更になっていますので、どのみち今の記述では思ったような結果は 得られませんね (^^ゞ > CLngやMid関数は「新しい関数」には含まれないと思うので、 CLng ・ Mid 関数などは、そうなんですが、その関数だけではお望みの抽出は できないです。 > *.*.*.1 > *.*.*.2 > *.*.*.4 > *.*.*.10 この * の部分の桁数が固定なら大丈夫ですけど、そこは固定じゃないんですよね? また、ドット(.) の数は、固定でいいのでしょうか? > ほかの人も使うので、私だけがアップデートしてもダメなので、 アップデートをしなくても、ユーザー定義関数として登録してやれば、使うことは できます。 複数台で使うのであれば、その方法を使った方が無難ですね。 とりあえず、「仕様」を固めないことには解決策の提示もできないので、そちらを じっくり検討し、再度お知らせください。 (でないと、無駄なやりとりが続くことになってしまいます。)

w-inty
質問者

お礼

回答ありがとうございます。 *.*.*.の部分の桁数は固定です。 ですので、「9文字目より右側」という固定条件で大丈夫です。 ドットの数も固定です。 上記の条件でしたので、9文字目より右のデータと入力したデータの突き合わせで検索、ということでできそうだな、と思ったのですが。

  • Gin_F
  • ベストアンサー率63% (286/453)
回答No.7

> OpenForm アクションの実行はキャンセルされました。 う~ん。。なんでしょ?? とりあえず、 > DoCmd.OpenForm "F_検索結果", acNormal, , WhereCond この前の行に、 Debug.Print WhereCond と入れてみてください。 実行すると、イミディエイトウィンドウにWhereCond の中身が出力されますので、 それを、こちらにUpしてください。

w-inty
質問者

お礼

回答ありがとうございます。 イミディエイトウィンドウに表示されたものは下記のものです。 (CLng(mid(T_テーブル.Date,9)) between 1 and 3) 何かおかしなところはありますでしょうか?

  • Gin_F
  • ベストアンサー率63% (286/453)
回答No.6

> 1.一番右の「.」の位置を検索 InStrRev 関数を使います。 > 2.それより右の数を抽出 Mid 関数で大丈夫ですね。 > 3.その抽出したものと入力したものが一致するかを検索する Right 関数の代わりに、上記関数を使ってやれば大丈夫だと思います。 condData = "(CLng(Mid(T_テーブル.Data,InstrRev(T_テーブル.Data,".")+1)) between " & Me!A.Value & " and " & Me!B.Value & ")" のように。 ただし、Access2000だと [ACC2000] 新しい VBA 関数を式で使用できない http://support.microsoft.com/default.aspx?scid=kb;ja;225956 なんてのがありますので、クエリ上で使うためには、 MicrosoftR Visual BasicR for Applications (VBA) アップデート - Q822150 http://www.microsoft.com/downloads/details.aspx?displaylang=ja&FamilyID=DA1A7ABA-CD3D-458B-9729-AB9094C9BD3F このアップデートをすれば大丈夫だと思います。

w-inty
質問者

お礼

回答ありがとうございます。 一番右の「.」ではなく、右から2番目の「.」の位置を抽出するにはどのようにしたらいいのでしょうか? 一番右だとちょっと不都合が出てしまいましたので、右から2番目、にしたいのです。

w-inty
質問者

補足

すいません、さきほどの書き込み(お礼)は気にしないでください(^^; condData = "(CLng(mid(T_テーブル.Data,9)) between " & Me!A.Value & " and " & Me!B.Value & ")" としてみたところ、やはり OpenForm アクションの実行はキャンセルされました。 と出てしまいました。 CLngやMid関数は「新しい関数」には含まれないと思うので、アップデートはとりあえず必要ないかな?と思い、やってません。 (ほかの人も使うので、私だけがアップデートしてもダメなので、するときはみんなしないといけないので…)

  • Gin_F
  • ベストアンサー率63% (286/453)
回答No.5

> 2桁のものもあれば3桁のものもあるんです。 > *.*.*.1 > *.*.*.2 > *.*.*.4 > *.*.*.10 IP アドレスの一番下の部分を条件にしたいとかなんでしょうか?? そうであれば、ちょっと面倒ですね。 お使いのAccessのバージョンはなんでしょうか? それによって、使える関数が違うので回答も変わってきますので (^^ゞ

w-inty
質問者

お礼

回答ありがとうございます。 >IP アドレスの一番下の部分を条件にしたいとかなんでしょうか?? はい、そんな感じです(^^; 私が今考えているのは 1.一番右の「.」の位置を検索 2.それより右の数を抽出 3.その抽出したものと入力したものが一致するかを検索する という感じです。 2.3.はなんとかなりますが、1.は…? MATCHとか使えば出ますでしょうか? INDEX? バージョンは2000以上でお願いします。

  • Gin_F
  • ベストアンサー率63% (286/453)
回答No.4

> 検索しているのは下記のようなデータです。 この形式だと、BETWEEN ~ AND ~ は使えないですね。 > 例えば検索キーに*.*.*.2から*.*.*.5 > condData = "(T_テーブル.Data between '" & Me!A.Value & "' and '" & Me!B.Value & "')" condData = "(Right$(T_テーブル.Data,1) between '" & Me!A.Value & "' and '" & Me!B.Value & "')" のようにすれば大丈夫だとは思いますけど。

w-inty
質問者

お礼

回答ありがとうございます。 変更したところ、 OpenForm アクションの実行はキャンセルされました。 と出てしまい、フォームが開きません。 またなんとなくですがRight$というのは、右側から○番目の…という用法でしょうか? 教えていただいたものだと、1となってますが、2桁のものもあれば3桁のものもあるんです。 我が儘いってもうしわけありません。

  • Gin_F
  • ベストアンサー率63% (286/453)
回答No.3

> condData = "(Val(T_テーブル.Data) between '" & Me!A.Value & "' and '" & Me!B.Value & "')" Val 関数を使っているってことは、数値型に変換されていますね。 なので、シングルクォーテーションも不要です。 Val 関数をはずすか、シングルクォーテーションをはずすかのどちらかになります。 condData = "(T_テーブル.Data between '" & Me!A.Value & "' and '" & Me!B.Value & "')" か condData = "(Val(T_テーブル.Data) between " & Me!A.Value & " and " & Me!B.Value & ")" のように。

w-inty
質問者

お礼

回答ありがとうございます。 アドバイスのように、Val関数を使わなくしました。 #2の方のお礼のところにもかいたのですが、エラーは出なくなったのですが、検索結果が意図するものと少々違います。 どのように変更したらいいのでしょうか?

回答No.2

ちと行間を読むのが下手なので勝手な想像も交えます。 [Data] フィールドはテキスト型だけど「日付型」と解釈できる値が入力されてる。(2004/01/01 とか) この質問文には BETWEEN 部分でエラーになったと書かれていますが、実際には他にも抽出条件を指定してませんか? エラーの説明でいきなり 'and(・・・' ってありますけど、この and ってなんですか? [Data] フィールド以外のフィールドにも条件式を設定してるんですか? 私のところで実験した限り、 テーブル名:tbl01 フィールド名:m01Name (テキスト型), m01Date (テキスト型) 上記テーブルを参照するフォーム:frm01Test Dim sWhere As String sWhere = "(m01Name = 'hoge') AND (m01Date BETWEEN #2004/01/01# AND #2004/12/31#)" DoCmd.OpenForm "frm01Test", acNormal, , sWhere これできちんと表示されていますよ。 もし [Data] フィールドだけしか条件式をせっていしないのでしたら WhereCond = WhereCond & "and" & condData の "and" が邪魔してませんかね。 とにかく質問文にあるコードよりも前の部分が見えないので何ともいえませんけど・・・ WhereCond = WhereCond & "and" & condData って、これ以前に WhereCond に何か入れてるんですか? strCount って・・・

w-inty
質問者

お礼

回答ありがとうございます。 ほかの箇所で使用していた検索VBAを流用しているので多少変なコードがあるかもしれません(笑 ちょっと変更してみました。 WhereCond = WhereCond & condData として、 WhereCond = Mid(WhereCond, strCount + 1) の箇所はなくしました。 その他#3の方のアドバイスのようにVal関数を使わなくしました。 エラーはでなくなったのですが、検索結果が想像していたものと違う…。 検索しているのは下記のようなデータです。 *.*.*.1 *.*.*.2 *.*.*.4 *.*.*.10 例えば検索キーに*.*.*.2から*.*.*.5 とした場合には *.*.*.2 *.*.*.4 と出てほしいのですが…。

  • Gin_F
  • ベストアンサー率63% (286/453)
回答No.1

テキスト型の場合は、前後をシングルクォーテーションでくくります。 # は、日付/時刻型の場合ですね。 > condData = "(T_テーブル.Data between #" & Me!A.Value & "# and #" & Me!B.Value & "#)" condData = "(T_テーブル.Data between '" & Me!A.Value & "' and '" & Me!B.Value & "')"

w-inty
質問者

お礼

回答ありがとうございます。 すいません、書いたのが間違ってました(>_<) 実際は以下のようにやってました。 condData = "(Val(T_テーブル.Data) between " & Me!A.Value & " and " & Me!B.Value & ")" で、教えられたようにシングルクォーテーションをつけてみました。 condData = "(Val(T_テーブル.Data) between '" & Me!A.Value & "' and '" & Me!B.Value & "')" ですが実行すると、同じようなエラーが出てしまいます。。。

関連するQ&A