Access (VBA) |
![]() ![]() |
(Windows 10 Pro : Access 2021)
連番が振れません
投稿日時: 23/07/12 18:54:19
投稿者: human
|
---|---|
いつもお世話になっております
|
![]() |
投稿日時: 23/07/13 11:34:00
投稿者: human
|
---|---|
追記です
|
![]() |
投稿日時: 23/07/13 16:14:30
投稿者: sk
|
---|---|
現時点では「まず[SID]の変換の規則と順序を矛盾も破綻もしない形で明文化するのが先」
引用: 1. [SID]の値に含まれている全ての半角/全角スペースを空文字列に置換する。 引用: 引用: 2. 全てのレコードに対して上記 1 の置換処理を施した状態において、 [SID]の値の長さが 15 文字を超える場合は、 [SID]の値を "NEWNO==" という文字列に書き換える。 引用: 3. 全てのレコードに対して上記 1 の置換処理を施した状態において、 [SID]の値の長さが 15 文字以内である場合は、上記 2 の処理を実行しない。 とりあえずここまではいいとして、 引用: 引用: 全角のアルファベット、全角の算用数字、全角のハイフンの扱いが不明瞭です。 (どこにも例示されていない) 引用: 引用: また「変換後の[SID]の値が同一であるレコードが他にも存在する場合は、 それらのグループごとに連番(区切り記号としての半角アンダースコアと、1 から始まる ゼロ埋め整数連番 3 桁)を付加する」というルールを適用しようとしているとして、 上記 3 に該当するケースにおいて、そのレコードの[SID]の値の長さが 12 〜 15 文字である場合、単純にグループ別連番(区切り記号込みで 4 文字)を 付加すれば、当然 15 桁の制限を超えることになります。 その場合はどのようにされるつもりなのでしょうか。 |
![]() |
投稿日時: 23/07/13 20:03:56
投稿者: human
|
---|---|
sk様
|
![]() |
投稿日時: 23/07/14 10:13:50
投稿者: sk
|
---|---|
引用: 例えば、[一時SID]の値が "0123456789ABCDE" であるレコードが 2 件以上存在した場合、それぞれのレコードの[新SID]の値は どのようになればよいのでしょうか。 |
![]() |
投稿日時: 23/07/14 12:00:19
投稿者: Suzu
|
---|---|
求めたい値と、例の間に 違いが見えます。
human さんの引用: 例との対比をすると 引用: SEQ 959 が 1行目、1084が、2行目 という認識で良いでしょうか? 一時SID NEWNO== に当てはめると その時、の処理コードは NewLOT = NewLOT & "_2行目以降_" & Format((CStr(ii)), "0") の様な形であり、求めたい値は NOWNO==_2行目以降_2 と言う事でしょうか? 100件目だと? NewLOT = NewLOT & "_2行目以降_" & Format((CStr(ii)), "#00") NOWNO==_2行目以降_100 ・・・ 17桁と読めますが良いのでしょうか? |
![]() |
投稿日時: 23/07/14 12:21:37
投稿者: Suzu
|
---|---|
分岐先が違いましたね。
引用: |
![]() |
投稿日時: 23/07/14 17:39:26
投稿者: Suzu
|
---|---|
SQL で求める時
|
![]() |
投稿日時: 23/07/18 10:32:07
投稿者: human
|
---|---|
sk様
|
![]() |
投稿日時: 23/07/18 11:11:33
投稿者: hatena
|
---|---|
human さんの引用: 同じコードが存在する場合は、"_001"という書式の連番を追加するということですね。 ただし、『NEWNO==』だった場合は、"001"という書式(ハイフンがなくなる)ということですね。 コードが12桁以上だと"_001"という書式の連番を付加すると15桁をオーバーするので、"NEWNO=="に変換して"001"という書式の連番を追加するということでいいですか。 |
![]() |
投稿日時: 23/07/18 13:19:27
投稿者: human
|
---|---|
hatena様
|
![]() |
投稿日時: 23/07/18 15:26:34
投稿者: sk
|
---|---|
引用: 引用: (標準モジュール) -------------------------------------------------------------------- Sub ConvertSerialId() '定数の宣言 Const SourceTableName As String = "TBL_展開_元" '参照元テーブル名 Const DestinationTableName As String = "TBL_展開_先" '出力先テーブル名 Const KeyPrefixOnError As String = "NEWNO==" 'エラー時のキー接頭辞 Dim db As DAO.Database Dim strSQL As String 'カレントデータベースの参照 Set db = CurrentDb '出力先テーブルの全てのレコードを削除 strSQL = "DELETE * FROM [" & DestinationTableName & "];" Debug.Print strSQL db.Execute strSQL, dbFailOnError '参照元テーブルのレコードを出力先テーブルに追加する。 'その際、[一時SID]には[SID]と同じ値を出力する。 strSQL = "INSERT INTO [" & DestinationTableName & "] " & _ "([SEQ],[SID],[一時SID],[新SID])" & _ " SELECT t1.[SEQ], t1.[SID], t1.[SID], Null" & _ " FROM [" & SourceTableName & "] t1;" Debug.Print strSQL db.Execute strSQL, dbFailOnError '出力先テーブルの全てのレコードの[一時SID]の値に含まれる '半角/全角スペースを取り除く '([一時SID]の値が Null である場合は空文字列として扱う) strSQL = "UPDATE [" & DestinationTableName & "] t1" & _ " SET t1.[一時SID] = Replace(Nz(t1.[一時SID],""""),"" "","""",1,-1,1);" Debug.Print strSQL db.Execute strSQL, dbFailOnError '出力先テーブルのレコードのうち、[一時SID]の値が空文字列であるレコードの '[一時SID]の値をエラー時キー接頭辞に書き換える strSQL = "UPDATE [" & DestinationTableName & "] t1" & _ " SET t1.[一時SID] = """ & KeyPrefixOnError & """" & _ " WHERE t1.[一時SID]="""";" Debug.Print strSQL db.Execute strSQL, dbFailOnError '出力先テーブルのレコードのうち、[一時SID]の値に2バイト文字が含まれているレコードの '[一時SID]の値をエラー時キー接頭辞に書き換える strSQL = "UPDATE [" & DestinationTableName & "] t1" & _ " SET t1.[一時SID] = """ & KeyPrefixOnError & """" & _ " WHERE Len(t1.[一時SID]) < LenB(StrConv(t1.[一時SID],128))" & _ " AND [一時SID] <> """ & KeyPrefixOnError & """;" Debug.Print strSQL db.Execute strSQL, dbFailOnError '出力先テーブルのレコードのうち、[一時SID]の値に 'ハイフン、アルファベット、数字のどれにも該当しない文字が含まれるレコードの '[一時SID]の値をエラー時キー接頭辞に書き換える strSQL = "UPDATE [" & DestinationTableName & "] t1" & _ " SET t1.[一時SID] = """ & KeyPrefixOnError & """" & _ " WHERE t1.[一時SID] Like ""*[!-0-9a-z]*""" & _ " AND [一時SID] <> """ & KeyPrefixOnError & """;" Debug.Print strSQL db.Execute strSQL, dbFailOnError '出力先テーブルのレコードのうち、[一時SID]の値の長さが 15 文字を超えるレコードの '[一時SID]の値をエラー時キー接頭辞に書き換える strSQL = "UPDATE [" & DestinationTableName & "] t1" & _ " SET t1.[一時SID] = """ & KeyPrefixOnError & """" & _ " WHERE Len(t1.[一時SID]) > 15" & _ " AND t1.[一時SID] <> """ & KeyPrefixOnError & """;" Debug.Print strSQL db.Execute strSQL, dbFailOnError '出力先テーブルの全てのレコードの[一時SID]の値に含まれる 'アルファベットを大文字に変換する strSQL = "UPDATE [" & DestinationTableName & "] t1" & _ " SET t1.[一時SID] = StrConv(t1.[一時SID],1)" & _ " WHERE t1.[一時SID] <> """ & KeyPrefixOnError & """;" Debug.Print strSQL db.Execute strSQL, dbFailOnError '出力先テーブルのレコードのうち、[一時SID]の値の長さが 12 文字を超え、 'かつ「[一時SID]の値が等しく[SEQ]の値が等しくない(他の)レコード」が存在するレコードの '[一時SID]の値をエラー時キー接頭辞に書き換える strSQL = "UPDATE [" & DestinationTableName & "] t1" & _ " SET t1.[一時SID] = """ & KeyPrefixOnError & """" & _ " WHERE Len(t1.[一時SID]) > 12" & _ " AND t1.[一時SID] <> """ & KeyPrefixOnError & """" strSQL = strSQL & _ " AND EXISTS(" & _ "SELECT t2.* " & _ " FROM [" & DestinationTableName & "] t2" & _ " WHERE t2.[一時SID] = t1.[一時SID]" & _ " AND t2.[SEQ] <> t1.[SEQ]" & _ ");" Debug.Print strSQL db.Execute strSQL, dbFailOnError '出力先テーブルのレコードのうち、「[一時SID]の値が等しく '[SEQ]の値が等しくない(他の)レコード」が存在しないレコードの '[新SID]の値を[一時SID]と同じ値に書き換える strSQL = "UPDATE [" & DestinationTableName & "] t1" & _ " SET t1.[新SID] = t1.[一時SID]" strSQL = strSQL & _ " WHERE NOT EXISTS(" & _ "SELECT t2.* " & _ " FROM [" & DestinationTableName & "] t2" & _ " WHERE t2.[一時SID] = t1.[一時SID]" & _ " AND t2.[SEQ] <> t1.[SEQ];" & _ ")" Debug.Print strSQL db.Execute strSQL, dbFailOnError '出力先テーブルのレコードのうち、[新SID]の値が Null である '(前述の SQL における条件に該当しない)レコードの '[新SID]の値を「[一時SID]の値の後ろにゼロ埋め3桁連番([SEQ]の昇順)を '付加した文字列」に書き換える strSQL = "UPDATE [" & DestinationTableName & "] t1" & _ " SET t1.[新SID] = t1.[一時SID] & Format(DCount(""*"",""" & DestinationTableName & """,""[一時SID]='"" & t1.[一時SID] & ""' AND [SEQ]<="" & t1.[SEQ]),""000"")" strSQL = strSQL & _ " WHERE t1.[新SID] IS NULL;" Debug.Print strSQL db.Execute strSQL, dbFailOnError Set db = Nothing End Sub-------------------------------------------------------------------- 以上のようなコードを実行できればよい、ということでしょうか。 |
![]() |
投稿日時: 23/07/18 15:27:09
投稿者: Suzu
|
---|---|
23/07/14 17:39:26 のSQL でも 一通りの分岐 条件を得る所までは
strSQL = "SELECT *, " & _ "(" & _ "SELECT COUNT(*) " & _ "FROM TBL_展開_元 AS AA " & _ "WHERE AA.一時SID = A.一時SID" & _ ") AS LDCount " & _ "FROM TBL_展開_元 AS A " & _ "ORDER BY 一時SID ASC, SEQ ASC;" Set rs = DB.OpenRecordset(strSQL, dbOpenDynaset) Do While Not rs.EOF i = i + 1 rs.Edit If rs![LDCount] = 1 Then rs![新SID] = rs![一時SID] Else If rs![新SID] = NewLOT Then ii = ii + 1 Else ii = 1 End If If rs![変換#] < 5 Then Moji = "_" Select Case Len(rs![一時SID] & Moji) Case Is < 13 rs![新SID] = rs![一時SID] & Moji & Format(ii, "000") Case 13 rs![新SID] = rs![一時SID] & Moji & Format(ii, "00") Case 14 rs![新SID] = rs![一時SID] & Moji & Format(ii, "0") Case Else End Select End If rs.Update NewLOT = rs![新SID] rs.MoveNext Loop |
![]() |
投稿日時: 23/07/18 18:38:37
投稿者: human
|
---|---|
sk様
|
![]() |
投稿日時: 23/07/19 14:43:03
投稿者: sk
|
---|---|
引用: ・ConvertSerialId プロシージャを実行したが、いずれかのステートメントにおいて 何らかの実行時エラーが発生し、コードの実行が中断された。 ・最後のステートメントまで実行されたが、[TBL_展開_先]には 何のレコードも出力されなかった。 (レコード件数が 0 件である) ・最後のステートメントまで実行されたが、[TBL_展開_先]に出力された 一部の(または全ての)レコードの[新SID]の値が変換規則通りに出力されなかった。 ・上記以外。 いずれの意味でおっしゃっているのでしょうか。 |
![]() |
投稿日時: 23/07/19 14:49:05
投稿者: human
|
---|---|
sk様
|
![]() |
投稿日時: 23/07/19 15:15:41
投稿者: sk
|
---|---|
引用: 引用: その場合、「参照元であるテーブル[TBL_展開_元]には そもそも何のレコードも格納されていない」 (INSERT INTO 文によって[TBL_展開_先]に追加されるべき レコードが 1 件もない)以外の原因はあり得ません。 |
![]() |
投稿日時: 23/07/19 15:39:38
投稿者: Suzu
|
---|---|
テストが不十分でした。 失礼しました。
strSQL = _ "SELECT *, DCOUNT(""*"",""TBL_展開_元"",""一時SID='"" & TBL_展開_元.一時SID & ""'"") AS LDCount " & _ "FROM TBL_展開_元 " & _ "ORDER BY 一時SID ASC, SEQ ASC;" Set rs = DB.OpenRecordset(strSQL, dbOpenDynaset) Do While Not rs.EOF i = i + 1 rs.Edit If rs![LDCount] = 1 Then rs![新SID] = rs![一時SID] Else If rs![一時SID] = NewLOT Then ii = ii + 1 Else ii = 1 End If If rs![変換#] < 5 Then Moji = "_" Else Moji = "" End If Select Case Len(rs![一時SID] & Moji) Case Is < 13 rs![新SID] = rs![一時SID] & Moji & Format(ii, "000") Case 13 rs![新SID] = rs![一時SID] & Moji & Format(ii, "00") Case 14 rs![新SID] = rs![一時SID] & Moji & Format(ii, "0") Case Else End Select End If rs.Update NewLOT = rs![一時SID] rs.MoveNext Loop ここまでコードを書ける方であれば、 条件分岐 変換# の分岐で、Else時の分岐が必要 であり 5の時とそれ以外の時 で、 変数 Moji が「_」「何もない」となる必要がある これは 理解できると思いっていただけに残念です。 (当方の検討が不十分なのを棚に上げてなので・・すみません) 希望動作のコード そのモノも提示しましたので、当方はここまでの区切りとさせていただきます。 |
![]() |
投稿日時: 23/08/26 15:06:06
投稿者: human
|
---|---|
いろいろありがとうございました
|