- ベストアンサー
ACCESS2000で変数の扱い方について
ある変数を用いて、テーブルの項目名の参照の仕方が知りたいのですが 具体的には。。。 ACCESS2000でAとB二つのテーブルがあります。 Aには 項目No. (オートNo.) 項目名 (文字) Bには コード (数値) 名称 (文字) カナ (文字) 住所1 (文字) 住所2 (文字) という構成になっています。 Aの項目名には、Bの名称以下の列名(名称、カナ、住所1,2)という レコードが入っています。 ここで、Bの文字型の項目を全て64バイト以下にするという事をやりたいのですが、 今後もBの項目は増えていくことが予想されますので、 一つづつコードを書いていくのは大変なので、以下の方法を考えました。 1.Aの1レコード目の項目名を変数Xに代入 2.B上の列名Xを1レコード目から順番に64バイト以下に変換 3.Bのレコード全て終わった段階で、変数XにAの次レコードの項目名を代入 4.Aのレコードがなくなるまで、2へ戻る Do Until A.EOF X=A.項目名 '変数XへAの項目名を代入 Do Until B.EOF B.Edit B!X= LeftB(B!X,64) 'Bの列名Xの文字数を64へ変換 ~~~~~~~~~~~~~~~~~~ B.Update B.MoveNext LOOP A.MoveNext LOOP というコードを書いたのですが ~~~~部分の”B!X”だとテーブルBのXに入っている列名を認識しません。 どのように記述すればいいのか、教えてください。 また、以前から参照していたACCESSの質問掲示板HPが なくなってしまい、困っています。そのようなHPをご存知でしたら 教えていただきたいです。
- みんなの回答 (7)
- 専門家の回答
質問者が選んだベストアンサー
B.Fields(X)=LeftB(B.Fields(X),64) ですね。 「B!X」では、レコードセット「B」の「X」というフィールドを見に行ってしまいます。(当然、「X」というフィールドが無い為にエラーになります。) Fieldsコレクションを使えば、個々のフィールドに対して「文字列」としてアクセスできます。例えば、 B.Fields("名称") = … などと書いた場合には、Bのフィールドの「名称」、というような感じで扱うことが出来るのです。 上記は、 X="名称" B.Fields(X) = … というように、2行に分割して書くことも出来ます。
その他の回答 (6)
- ARC
- ベストアンサー率46% (643/1383)
>今までの回答を見るとACCESS2000ではクエリで簡単にというのはムリのようですね。 ん~、そういう訳でもないですよ。確かにクエリのみで半角全角を区別した切り出しは出来ませんが、標準モジュールを作成し、#5みたいな感じの関数を(Public Function として)そこに登録しておけば、クエリからでも同関数が使用できますので。 あと、Access2000からはデータベースへの文字列の格納方式がUnicode造りになっていますので、例えばフィールド長が「64」のテキスト型フィールドに255文字の文字列を無理やり格納しようとするならば、LeftBを使わずに、Left関数を使って B.Fields(X)=Left(B.Fields(X),64) とするだけでOKです。(Unicodeは全角も半角も区別しないので、単純に64文字を切り取るだけでいいのです。)
お礼
なるほど、いろいろな方法があるものですね。 ただやはり、なんとなくACESS2000からは文字列数の扱いが不便になった 感じはしてしまいますが。 ARCさん色々ありがとうございました。
- maruru01
- ベストアンサー率51% (1179/2272)
ARCさん、フォローありがとうございます。 >半端な長さの文字列を切り出したときに全角文字の前半バイトが残ってしまいますよね。 その通りですね。見た目は無くても、残っちゃいますね。 それにしても、これだとすごく面倒ですね。 質問者のshachihocoさんは、本当に半角1バイト、全角2バイトとしての切り取りをやりたいのでしょうか。
お礼
おっしゃる通り半角1バイト、全角2バイトの扱いを望んでました。 たしかに面倒ですが、しょうがないんでしょうか。 ACCESS97だとクエリでLENB関数を使うと簡単にバイト数がわかって便利だったんですが、今までの回答を見るとACCESS2000ではクエリで簡単にというのはムリのようですね。 色々ありがとうございました。
- ARC
- ベストアンサー率46% (643/1383)
すいません。ちょっとだけ揚げ足を取らせてください。 (maruru01さん、ごめんなさい。) fld.Value = StrConv(LeftB(StrConv(fld.Value ,vbFromUnicode),64),vbUnicode) では、半端な長さの文字列を切り出したときに全角文字の前半バイトが残ってしまいますよね。 きちんと全角半角を区別した上で切り出すには、以下のような関数が必要です。 切り出し後の文字列 = TrimString(切り出し前の文字列, バイト長) です。 Function TrimString(strInput As String, lngLength As Long) As String Dim strTmp As String Dim bytTmp As Byte 'SJISにして切り出す strTmp = LeftB(StrConv(strInput, vbFromUnicode), lngLength) '末尾が「2バイト文字の1バイト目」かどうかをチェック bytTmp = AscB(RightB(strTmp, 1)) If (bytTmp >= &H81 And bytTmp <= &H9F) Or _ (bytTmp >= &HE0 And bytTmp <= &HFC) Then '1バイト目なら、切り出し長よりも1バイト短くする strTmp = LeftB(strTmp, lngLength - 1) End If 'Unicodeに戻す TrimString = StrConv(strTmp, vbUnicode) End Function 時間節約のために「素直」に書いたので… 探せばもっとスマートなアルゴリズムがあるかも…
お礼
これまた、非常に勉強になりました。いろいろな場所で使う機会が多そうです。 ありがとうございました。
- maruru01
- ベストアンサー率51% (1179/2272)
こんにちは。maruru01です。 Aテーブルを使用せずに、Bテーブルの文字型フィールド(テキストとメモ)のみ変更する方法です。 フィールドのデータ型がテキスト(adVarWChar)かメモ(adLongVarWChar)なら、変更します。 この方法なら、Aテーブルは必要ありません。 Dim cn As ADODB.Connection Dim rs As ADODB.RecordSet Dim fld As ADODB.Field Set cn = CurrentProject.Connection Set rs = New ADODB.RecordSet rs.Open "B", cn, adOpenKeyset, adLockOptimistic Do Until rs.EOF For Each fld In rs.Fields If fld.Type = adVarWChar Or fld.Type = adLongVarWChar Then fld.Value = LeftB(fld.Value, 64) End If Next fld rs.Update rs.MoveNext Loop rs.Close: Set rs = Nothing cn.Close: Set cn = Nothing あと、Typeメソッドの戻り値が載っているMicrosoftのページのURLも紹介しておきます。 http://www.microsoft.com/JAPAN/developer/library/vbaac10/acdatComparisonDataTypes.htm それから、バイトと文字数に関しては、No.3のaptivaさんの指摘通りですね。 単に文字数なら、LeftBではなく、Left関数でいいわけですが。 半角1バイト、全角2バイトでバイト数でやるなら、 fld.Value = StrConv(LeftB(StrConv(fld.Value ,vbFromUnicode),64),vbUnicode) となります。(残り1バイトでの全角は切り捨て)
お礼
回答ありがとうございます。 こんな方法があったのですね。これなら、Bに項目が増えても気にすることはないわけですね。非常に勉強になりました。なんだか見たことのない記述もありますが、挑戦してみたいと思います。
- aptiva
- ベストアンサー率36% (193/529)
>ここで、Bの文字型の項目を全て64バイト以下にするという事をやりたいのですが、 64”バイト”というのは、なかなか難しいですね。 半角=1バイト、全角=2バイトの想定ではないですか? LeftB関数を使っても、Access2000では内部コードが半角文字も全角文字も2バイトなので、目的に合うかどうか心配です。 LeftB("ABCDEF",4)の結果は、"AB"(半角) LeftB("ABCDEF",4)の結果は、"AB"(全角) になります。
お礼
ACCESS97の時はLEFTBでできた気がするのですが、ACCESS2000のHELPで見ると 変わってしまったようですね。回答No.4以降でこれも解決しました。 ご忠告ありがとうございます。
- 20020718
- ベストアンサー率48% (13/27)
B!X= LeftB(B(X),64) ではどうですか?
お礼
おっしゃるとおりのエラーが出ていたのですが、見事解決しました。 ありがとうございました。