Microsoft Access 掲示板

6,622 件中 4,601 から 4,640 までを表示しています。
20
シソンヌ 2020/11/30 (月) 15:55:04 0029a@1c915 >> 19

バッチリうまくいきました。ありがとうございます😊

19

txtBは「txtB」という名前のコントロール(またはフィールド)そのものを参照します。コントロール名を動的に生成して参照するなら、文字列を受け取ってコントロールを参照するようなアクションを使う必要があります

それと、計算順の問題で数値部分は先に計算させる(括弧で囲む)必要がありますね

Me("txtB" & (sCount + 1)) = strSplit(sCount)
18
シソンヌ 2020/11/30 (月) 12:31:40 0029a@1c915

更に初心者の質問で申し訳ありません。
    Debug.Print strSplit(sCount)
の部分についてですが、テキストボックスに1個ずつ格納していきたいと思っています。

テキストボックス名 txtB & scount + 1 として

txtB & sCount + 1 = strSplit(sCount)

というのは、不可能のようですね。。
変数名のカウントアップはどうしたらよいのでしょうか。

17
シソンヌ 2020/11/30 (月) 11:57:44 0029a@1c915 >> 16

大変悩んでいたので本当に助かります。
じっくり内容を確認し、勉強させていただきます!!本当にうれしいです。
ありがとうございます。

2
wasabi 2020/11/30 (月) 11:24:30 d94c8@d1b14

hatenaさん
返信ありがとうございます。

Excel
新規ブックを開いて、
A1セルに 00LJ と入力
B2セルに AU87 と入力
上記のセルをそれぞれコピーして、Accessのテーブルのフィールドに貼り付け

⇒上記手順を試したところ、新規で作成したエクセルのデータは問題なく貼付できました。

使用しようとしているエクセルデータの方に、何かしら問題があるのかもしれません。
エクセル側データを今一度確認し、問題がないようなら、
0始まりおよびアルファベットから始まるフィールドが関与しない方法で
クエリを作成するなど他の対応方法を検討してみます・・・

16
hiroton 2020/11/30 (月) 10:52:10 修正 c38ce@f966d

とりあえずUnicodeのことは忘れて、次の例を考えます。

1 2 3 4 5 6 7 8

この場合、たとえばMidh(str, a, b)のような関数を作ったとしてMidh("あイうエお", 5, 3)としたとき、「う」はどう扱ったらいいでしょうか?

半角を1、全角を2とカウントするようなMidのような関数は現実的ではないでしょう
このようなことをする場合は、すべての文字をひとくくりに考える必要があります

半角を含む文字列を処理する関数「splith()」

Function splith(str As String, n As Long) As String()
'//ANSI(半角1バイト、全角2バイト)を利用してnカウント以内で分割した文字列の配列を返す関数
    Dim strBase As String, strAnsi As String, str1 As String, str2 As String, strLeft As String
    Dim sCount As Long
    
    Dim strSplit() As String
    
    strBase = str
    Do Until strBase = ""
        ReDim Preserve strSplit(sCount)
        strAnsi = strConv(strBase, vbFromUnicode)
        
        '//合計nカウント以内だったらそのまま取り出して終わり
        If LenB(strAnsi) <= n Then
            strSplit(sCount) = strBase
            Exit Do
        End If
        
        '//nカウント目の文字をチェックして2バイト文字なら切り捨てる
        str1 = strConv(LeftB(strAnsi, n), vbUnicode)
        str2 = strConv(LeftB(strAnsi, n + 1), vbUnicode)
        If Len(str1) = Len(str2) Then
            '//2バイト文字から1バイト取り出したら文字数は1(文字は化けるが文字数は1)
            '//余分に1バイト取り出しても正常な文字として文字数は1で、全体の文字数は変わらない
            '//nカウント目の文字が2バイト文字の前半1バイトだったので1バイト減らす
            strLeft = strConv(LeftB(strAnsi, n - 1), vbUnicode)
        Else
            '//余分に1バイト取り出して文字数が変わったらnカウントでちょうど文字の区切りだった
            strLeft = str1
        End If
        
        '//取り出した文字を配列に保存
        strSplit(sCount) = strLeft

        '//取り出した文字分だけ元の文字を取り除く
        strBase = Mid(strBase, Len(strLeft) + 1)

        '//配列の次の要素の準備
        sCount = sCount + 1
    Loop

    splith = strSplit()
End Function

テストコード

Private Sub コマンド0_Click()
Dim strBase As String
Dim strSplit() As String
Dim sCount As Long

strBase = Me!テキスト

If strBase = "" Then Exit Sub

If strBase <> strConv(strConv(strBase, vbFromUnicode), vbUnicode) Then
    MsgBox "非対応の文字が見つかりました。処理を中断します"
    Exit Sub
End If

strBase = strConv(strBase, vbNarrow)
strSplit() = splith(strBase, 20)

For sCount = 0 To UBound(strSplit)
    Debug.Print strSplit(sCount)
Next
End Sub

出力結果

このページの下の「新し
いトピックを作る」ボタンを
クリックして質問を入力し
てください。あるいは
下記のリンクをクリックして
ください。
2
hideki 2020/11/29 (日) 22:06:11 09c37@96514

ありがとうございました。

15
シソンヌ 2020/11/29 (日) 21:17:23 f1ed8@e2de4 >> 14

全然違いますね。。
他も試してみたのですがやはりうまく行きません😓

14
シソンヌ 2020/11/29 (日) 19:20:02 f1ed8@e2de4 >> 13

Len(M)の間違いでした。。
あと、初心者で申し訳ないのですが、
$マークは、どういう意味があるのでしょうか?

13
シソンヌ 2020/11/29 (日) 19:17:35 f1ed8@e2de4

お騒がせしております。
今気づいたのですが、
res = Mid$(S, M, Len(res))

res = Mid$(S, LenAnsiB(M), Len(res))
でしょうか。。
あとで試してみます。

1

ID 毎の標準偏差を求めたいなら、クエリのデザインビューは下記にしてください。

フィールド:ID: Left([社員ID],16)AAA
集計:グループ化標準偏差

ID以外のフィールドをグループ化しますと、グループ内件数が1件になってしまうので標準偏差は求められません。

SQLなら、

SELECT Left(社員ID, 16) AS ID, StDev(AAA) AS AAA標準偏差
FROM MT_AAA
GROUP BY Left(社員ID, 16);
12
シソンヌ 2020/11/28 (土) 21:27:18 0029a@1c915 >> 8

連結にしていましたが、[元テキスト]⇒txt元テキスト ・・・等々変更したら1回で表示されるようになりました。教えていただきありがとうございました。

11
シソンヌ 2020/11/28 (土) 21:14:23 0029a@1c915 >> 10

反映させる部分↓

        cnt = cnt0 + 1
        str1 = MidAnsiB([テキスト], cnt, TEST_COUNT)
        cnt1 = LenAnsiB(str1)
                
        cnt = cnt + cnt1
        str2 = MidAnsiB([テキスト], cnt, TEST_COUNT)
        cnt2 = LenAnsiB(str2)
10
シソンヌ 2020/11/28 (土) 21:10:08 0029a@1c915 >> 9

ありがとうございます。教えていただいた関数を参考に考えていますが、
行き詰っています。

今回文章を何個かに分割したいので、midで作って繰り返しさせたいと思っていますがうまくいきません・・・
どこが間違っているのでしょうか。
(とりあえず汎用関数の部分のみ↓)

Public Function MidAnsiB(S As String, M As Long, L As Long) As String
    Dim res As String, T As Long
 
    If S = "" Then Exit Function  '元テキストが空なら終了
     
    If LenAnsiB(S) <= L Then    '元テキストが任意の数以下ならそのまま出力して終了
        MidAnsiB = S
        Exit Function
    End If
     
    res = StrConv(MidB$(StrConv(S, vbFromUnicode), M, L), vbUnicode)    'コードを変えて文字数揃えてユニコードに戻す
 
    res = Mid$(S, M, Len(res))
 
    If LenAnsiB(res) > L Then
        res = Mid$(S, M, Len(res) - 1)
    End If
 
 
    'サロゲートペア文字対策
    Select Case AscW(Right$(res, 1))
    Case &HD800 To &HDBFF
        res = Left$(res, Len(res) - 1)
    End Select

    MidAnsiB = res
    
End Function

9

全角、半角に関しては、いろいろ複雑な事情があります。
とりあえず下記を参照してください。

半角1桁全角2桁で計算するLenB、LeftB関数の代替関数 - hatena chips

VBA Unicode 文字の入力や変換、読み込みについて

Unicode文字(Shift-JISにない文字)、サロゲートぺー文字の扱いはどうするのかまずは決める必要があると思います。

8

次の質問なのですが、現在ボタンを2回押さないと反映できません。

フォームは連結ですか、非連結ですか。

一応、非連結で下記のようなサンプルを作成して確認してみましたが、ボタン1回クリックで表示されました。

テキストボックス

  • txt元テキスト
  • txt変更テキスト
  • txt変更テキスト長さ

コマンドボタン

  • btn半角化
Private Sub btn半角化_Click()
    Me.txt変更テキスト = StrConv(Me.txt元テキスト, vbNarrow)
    Me.txt変更テキスト長さ = LenB(StrConv(Me.txt変更テキスト, vbFromUnicode))
End Sub
7
シソンヌ 2020/11/28 (土) 09:01:07 0029a@1c915 >> 6

この件ですが、21バイトだった場合19バイトで切り出したらいいですね・・
式を考え中ですが、また相談させていただくと思います。すみません。

5の質問について、解決法がわかれば助かります。

6
シソンヌ 2020/11/27 (金) 22:25:30 0029a@1c915

もう1つの質問を記載させていただきます。

現在以下のように、[テキスト]の文章を20バイトで区切ってテキストボックスで3つに分けるという処理をしています。

Private Sub btn項目用_Click()
Const COUNT As Long = 20
    Me.Refresh
        txt項目1 = StrConv(LeftB(StrConv([テキスト], vbFromUnicode), COUNT), vbUnicode)
        txt項目2 = StrConv(MidB(StrConv([テキスト], vbFromUnicode), COUNT + 1, COUNT), vbUnicode)
        txt項目3 = StrConv(MidB(StrConv([テキスト], vbFromUnicode), COUNT * 2 + 1, COUNT), vbUnicode)
       
        txt項目1長さ = LenB(StrConv([項目1], vbFromUnicode))
        txt項目2長さ = LenB(StrConv([項目2], vbFromUnicode))
        txt項目3長さ = LenB(StrConv([項目3], vbFromUnicode))

End Sub

このとき、うまく20バイトずつ文章が分かれてくれたらいいのですが
全角と半角が混ざった文章だと、文字化けしたり21バイトになったりします。
20バイト以下で、文字化けせずにうまくわけることはできませんでしょうか。

以上、ご検討いただければ幸いです。宜しくお願い致します。

5
シソンヌ 2020/11/27 (金) 17:27:48 0029a@1c915

下記コードで半角化&文字数を表示することができました!
ありがとうございました。

Private Sub btn半角化_Click()
    Me.Refresh
    txt変更テキスト = StrConv([元テキスト], 8)
    txt変更テキスト長さ = LenB(StrConv([変更テキスト], vbFromUnicode))
    Me.Refresh
End Sub

次の質問なのですが、現在ボタンを2回押さないと反映できません。
(それを解消できるかと思って「Me.Refresh」を2回入れているのですが・・だめでした)
1回で反映できる方法はありますでしょうか。

4
シソンヌ 2020/11/27 (金) 17:15:59 0029a@1c915 >> 2

半角化じゃなかった、文字コードの変更をすると文字化け、の間違いです。スミマセン。

3
シソンヌ 2020/11/27 (金) 17:13:39 0029a@1c915 >> 2

すみません。書きかけでエンターを押してしまいました。

Private Sub btn半角化_Click()
    Me.Refresh
    txt変更テキスト = StrConv([元テキスト], vbFromUnicode)
    Me.Refresh
End Sub

下記コードで半角化すると文字化けしますが、こちらは今までどおりの式にして
カウントだけ変更すればよいでしょうか、今から試してみます。

2
シソンヌ 2020/11/27 (金) 17:07:52 0029a@1c915 >> 1

ありがとうございます。とても参考になったのですが、うまく行きません。


1
名前なし 2020/11/27 (金) 16:14:07 d8dfb@f966d

Len 関数
その文字に何バイト使うか?というのは文字コードに依存します。(LenB関数の埒外)

String Data Type (Visual Basic)
VBAで文字を扱おうとすると基本、Unicodeで扱われます。Unicodeは半角、全角関係なく1文字を2バイトで表現する文字コードです。

半角カナ
いろいろあって、濁音や半濁音を表すときは2文字使うというのが現在です。

以上のことから質問の、

このページの下の「新しいトピックを作る」ボタンをクリックして質問を入力してください。あるいは下記のリンクをクリックしてください。

の例では4文字×2バイト増えた数字が表示されるのです。

半角1文字を1、全角1文字を2とカウントするためには、そう表現する文字コードに変換してLenB()を使う必要があります。最初のリンク先にある通り

LenB(StrConv(str, vbFromUnicode))

のような処理をさせます。

10
hatena 2020/11/27 (金) 10:52:13 修正

コンボボックスを非表示にすることはできますか?

表示/非表示の切り替えは、Visibleプロパティで可能です。

AccessVBAの基本8~可視・使用可能プロパティの変更

9
ポンタ 2020/11/27 (金) 10:44:40 0029a@1c915 >> 8

ご検討ありがとうございます。
そうですよね。申し訳ありません。
実際のファイルを送ることができないので、時間ができたら簡単なものを作ってみたいと思います。その前に、本件に関する別件で質問です。
(この件もファイルを送らないと伝わりづらかったら申し訳ありません、その場合は改めます)

上記コードの1つ目の件で、登録された企業はコンボボックスとテキストボックスを切り替えて表示しているのですが、未登録企業チェックを入れたときコンボボックスにロックをかけますが、表示されてしまうので紛らわしい状態です。(タブストップも適用される)
コンボボックスを非表示にすることはできますか?

1

現状ですと、どこのレコードソースを変更するのか分からない状態になっているかと思います。
フォームBのレコードソースを変更したい場合には下記になるかと。

Forms!フォームB.RecordSource

またSelect Caseに対応するEnd Selectがありませんので、
別のエラーも出ていると思います。

8

可能なら、実際のファイルを見せてもらった方が速いです。
コードだけでは全体像がつかめないし、出ている情報だけからサンプルを作成して動作確認するのもちょっと困難なので。

右カラムの下の方にあるファイル送信フォームから現状のファイルを送信てもらえませんか。
テーブルデータは個人情報も入っていると思いますので、削除しておいてください。

7
ポンタ 2020/11/27 (金) 00:51:48 0029a@1c915

早速の質問恐れ入ります。
まず、企業名はコンボボックスだったため以下設定にしてみました。(正しいでしょうか…?)

Private Sub cbo送付先企業ID_Enter()
    If Me.chk未登録 = True Then
    Else
    Me.cbo送付先企業ID.Requery
    End If
End Sub

Private Sub txt送付先企業_Enter()
    If Me.chk未登録 = True Then
    Else
    Me.cbo送付先企業ID.SetFocus
    End If
End Sub

そして、チェックをつけたりはずしたりした時の挙動がよくわからなかったので
実行のタイミングをチェックボックス更新にしてみました…問題ありますでしょうか。

Private Sub chk未登録_AfterUpdate()

(★ここに後述のコードを入れている)
    Call 未登録_AfterUpdate
End Sub

そして今困っている点です。チェックボックスを切り替えたとき、
不要な情報を消したいのですが、色々エラーが出てうまくいきません。。

(★上記の部分)

    If Me.chk未登録 = True Then
        Me.cbo送付先企業ID = Null
        Me.cbo送付先担当者ID = Null
    Else
        Me.txt送付先企業 = Null
        Me.txt送付先担当者 = Null
        Me.txt部署 = Null
        Me.txt郵便番号 = Null
        Me.txt住所1 = Null
        Me.txt住所2 = Null
    End If

まだ作成途中なので、これらの設定では今後不具合が出てくるのかもしれませんが
とりあえずチェックボックスの切替で悩んでいる状況です。

1

そのエラーがでるとき「F管理総合」フォームは開いてますか。
あるいは「F管理総合」がサブフォームということはないですか。

1

コンボボックスはフォームヘッダーに配置しているのですか。
フォームは帳票フォームですか。
フォームで新規レコードを入力できますか。

コンボボックスの値集合ソース、値集合タイプの設定を提示してください。

1

下記の手順で確認してみましたが、再現できませんでした。(普通に貼り付けできました。)

Access
テーブルを新規作成して、
データ型:短いテキスト
書式:@
のフィールドを追加

Excel
新規ブックを開いて、
A1セルに 00LJ と入力
B2セルに AU87 と入力

上記のセルをそれぞれコピーして、Accessのテーブルのフィールドに貼り付け

とりあえず、上記の手順をそちらでやってみてブランクになるという現象が発生しますか。

6
ポンタ 2020/11/26 (木) 22:01:38 0029a@1c915

ありがとうございます!
テキストボックスを切り替えることができるのですね!!すごい。
理解できたつもりですが、作成してみてわからないところがでてきたら改めて質問させていただきたいと思っています。
申し訳ありませんが、その際は宜しくお願い致します。
また、色々考えている内に本件について追加の欲望もでてきたので、その件も行き詰ったら質問させていただきたいと思っております。すみません。

5

不足している情報は勝手に推測して、テーブルは下記と仮定します。

T送付履歴
送付ID、発送日、会社ID、送付資料1、送付資料2、・・・

T会社情報
会社ID、会社名、部署名、郵便番号、住所1、住所2、・・・

先頭のフィールドが主キー

T送付履歴 に下記のフィールドを追加します。
仮(Yes/No型)、仮会社名、仮部署名、仮郵便番号、仮住所1、仮住所2

上記のテーブルからクエリを作成してフォームのレコードソースとします。
フォームは単票フォームとします。

会社名、部署名、郵便番号、住所1、住所2 のフィールドはテキストボックスとしてフォーム上に配置します。

「編集ロック」は「はい」にしておきます。(マスターが不用意に更新されないようにするため)
また、フィールドの追加やウィザードで配置したテキストボックスの名前はフィールド名と同じになっているので、それぞれの名前を、
txt会社名、txt部署名、txt郵便番号、txt住所1、txt住所2 というように変更しておきます。

あと「仮」フィールドもフォーム上に配置します。Yes/No型なので、チェックボックスになります。

フォームのモジュールに下記のイベントプロシージャを作成します。

'レコード移動時
Private Sub Form_Current()
    Call 仮_AfterUpdate
End Sub

'仮チェックボックス更新後処理
Private Sub 仮_AfterUpdate()
    If Me.仮 = True Then
        Me.txt会社名.ControlSource = "仮会社名"
        Me.txt会社名.Locked = False
        Me.txt部署名.ControlSource = "仮部署名"
        Me.txt部署名.Locked = False
        Me.txt郵便番号.ControlSource = "仮郵便番号"
        Me.txt郵便番号.Locked = False
        Me.txt住所1.ControlSource = "仮住所1"
        Me.txt住所1.Locked = False
        Me.txt住所2.ControlSource = "仮住所2"
        Me.txt住所2.Locked = False
    Else
        Me.txt会社名.ControlSource = "会社名"
        Me.txt会社名.Locked = True
        Me.txt部署名.ControlSource = "部署名"
        Me.txt部署名.Locked = True
        Me.txt郵便番号.ControlSource = "郵便番号"
        Me.txt郵便番号.Locked = True
        Me.txt住所1.ControlSource = "住所1"
        Me.txt住所1.Locked = True
        Me.txt住所2.ControlSource = "住所2"
        Me.txt住所2.Locked = True
    End If
End Sub

これで、仮チェックボックスにチェックを入れると、会社名、住所等を入力できるようになり、
仮会社名、仮住所1 ・・・に格納されます。

レポートでは、例えば会社名のテキストボックスのコントロールソースは、下記のように設定します。
=IIf([仮]=True,[仮会社名],[会社名])

以上、一例です。

3
トマト 2020/11/26 (木) 14:51:37 0029a@1c915

度々スミマセン。結局自己解決しました。

4
ポンタ 2020/11/26 (木) 13:14:36 0029a@1c915 >> 1

現在は郵送履歴は残していませんでしたが、残したいと思っていたので
先程記載した現状のフィールドに「発送日」も追加予定です。

3
ポンタ 2020/11/26 (木) 13:10:15 0029a@1c915 >> 2

フォームは帳票にしていますが、よく考えたら単票でもいいです。
都合の良い方で宜しくお願い致します。

2
ポンタ 2020/11/26 (木) 13:08:50 0029a@1c915

ご確認ありがとうございます。「F送付」のレコードソースはクエリになっています。
住所等の情報は「T会社情報」にあり、「Q送付」にひっぱっています。
Q送付のフィールド名は 送付ID、郵便番号、住所1、住所2、会社ID、会社名、部署名、氏名ID、氏名、送付資料1、送付資料2・・
といった感じです。

「普段は登録している企業を選択したら情報を引っ張ってくる」についてですが、
「F送付」の「cbo氏名ID」にて氏名を選択すると以下VBAが動きます。

Private Sub cbo氏名ID_AfterUpdate()
    Me.cbo氏名ID.Requery
    If Me.txt住所1 = "" Then
    
    MsgBox "住所が入力されていません。"
    ElseIf Me.txt郵便番号 = "" Then
    MsgBox "郵便番号が入力されていません。"
    End If
End Sub

フォームは帳票です。
アイデアがあるとうれしいです。ご検討ありがとうございます。

3
tokinaito 2020/11/26 (木) 11:52:31 10f3b@f6db2

hatena様大変ありがとうございました。

2
トマト 2020/11/26 (木) 10:17:11 0029a@1c915

ごめんなさい。修正して絞り込んだらうまく行ったとおもったのですが、勘違いでした。。
改めて、下記コードの修正部分を教えていただけると助かります。

Forms!F作品.Filter = "月>=#" & DateSerial(Year(Date), Month(Date), 1) & "# AND 月<#" & DateSerial(Year(DateAdd("m", 1, Date)), Month(DateAdd("m", 1, Date)), 1) & "# And (([条件1chk] = False And [条件1] Is Null) Or ([条件2chk] = False And [条件] Is Null))"

1
トマト 2020/11/26 (木) 10:09:27 0029a@1c915

Access上でしばらく悩んでいたので投稿したのですが、記載した途端間違いがわかりました。。
※orの部分を大かっこで囲む
スミマセン。お騒がせしました。