アプリ版:「スタンプのみでお礼する」機能のリリースについて

ある変数を用いて、テーブルの項目名の参照の仕方が知りたいのですが
具体的には。。。

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をご存知でしたら
教えていただきたいです。

A 回答 (7件)

B!X= LeftB(B(X),64)



ではどうですか?
    • good
    • 0

B.Fields(X)=LeftB(B.Fields(X),64)


ですね。

「B!X」では、レコードセット「B」の「X」というフィールドを見に行ってしまいます。(当然、「X」というフィールドが無い為にエラーになります。)

Fieldsコレクションを使えば、個々のフィールドに対して「文字列」としてアクセスできます。例えば、
B.Fields("名称") = …
などと書いた場合には、Bのフィールドの「名称」、というような感じで扱うことが出来るのです。

上記は、
X="名称"
B.Fields(X) = …
というように、2行に分割して書くことも出来ます。
    • good
    • 0
この回答へのお礼

おっしゃるとおりのエラーが出ていたのですが、見事解決しました。
ありがとうございました。

お礼日時:2002/09/11 21:46

>ここで、Bの文字型の項目を全て64バイト以下にするという事をやりたいのですが、



64”バイト”というのは、なかなか難しいですね。
半角=1バイト、全角=2バイトの想定ではないですか?
LeftB関数を使っても、Access2000では内部コードが半角文字も全角文字も2バイトなので、目的に合うかどうか心配です。
LeftB("ABCDEF",4)の結果は、"AB"(半角)
LeftB("ABCDEF",4)の結果は、"AB"(全角)
になります。
    • good
    • 0
この回答へのお礼

ACCESS97の時はLEFTBでできた気がするのですが、ACCESS2000のHELPで見ると
変わってしまったようですね。回答No.4以降でこれも解決しました。
ご忠告ありがとうございます。

お礼日時:2002/09/11 21:51

こんにちは。

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 …

それから、バイトと文字数に関しては、No.3のaptivaさんの指摘通りですね。
単に文字数なら、LeftBではなく、Left関数でいいわけですが。
半角1バイト、全角2バイトでバイト数でやるなら、

fld.Value = StrConv(LeftB(StrConv(fld.Value ,vbFromUnicode),64),vbUnicode)

となります。(残り1バイトでの全角は切り捨て)
    • good
    • 0
この回答へのお礼

回答ありがとうございます。
こんな方法があったのですね。これなら、Bに項目が増えても気にすることはないわけですね。非常に勉強になりました。なんだか見たことのない記述もありますが、挑戦してみたいと思います。

お礼日時:2002/09/11 21:55

すいません。

ちょっとだけ揚げ足を取らせてください。
(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

時間節約のために「素直」に書いたので…
探せばもっとスマートなアルゴリズムがあるかも…
    • good
    • 0
この回答へのお礼

これまた、非常に勉強になりました。いろいろな場所で使う機会が多そうです。
ありがとうございました。

お礼日時:2002/09/11 22:04

ARCさん、フォローありがとうございます。



>半端な長さの文字列を切り出したときに全角文字の前半バイトが残ってしまいますよね。
その通りですね。見た目は無くても、残っちゃいますね。

それにしても、これだとすごく面倒ですね。
質問者のshachihocoさんは、本当に半角1バイト、全角2バイトとしての切り取りをやりたいのでしょうか。
    • good
    • 0
この回答へのお礼

おっしゃる通り半角1バイト、全角2バイトの扱いを望んでました。
たしかに面倒ですが、しょうがないんでしょうか。
ACCESS97だとクエリでLENB関数を使うと簡単にバイト数がわかって便利だったんですが、今までの回答を見るとACCESS2000ではクエリで簡単にというのはムリのようですね。
色々ありがとうございました。

お礼日時:2002/09/11 22:07

>今までの回答を見るとACCESS2000ではクエリで簡単にというのはムリのようですね。



ん~、そういう訳でもないですよ。確かにクエリのみで半角全角を区別した切り出しは出来ませんが、標準モジュールを作成し、#5みたいな感じの関数を(Public Function として)そこに登録しておけば、クエリからでも同関数が使用できますので。

あと、Access2000からはデータベースへの文字列の格納方式がUnicode造りになっていますので、例えばフィールド長が「64」のテキスト型フィールドに255文字の文字列を無理やり格納しようとするならば、LeftBを使わずに、Left関数を使って

B.Fields(X)=Left(B.Fields(X),64)

とするだけでOKです。(Unicodeは全角も半角も区別しないので、単純に64文字を切り取るだけでいいのです。)
    • good
    • 0
この回答へのお礼

なるほど、いろいろな方法があるものですね。
ただやはり、なんとなくACESS2000からは文字列数の扱いが不便になった
感じはしてしまいますが。
ARCさん色々ありがとうございました。

お礼日時:2002/09/12 16:14

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!