【问题标题】:Auto-Increment Letter to specific Number特定数字的自动递增字母
【发布时间】:2019-04-15 01:19:21
【问题描述】:

我在自动递增字母方面需要帮助。

Table1 中的描述字段具有如下值:B39

这个Table1 Record,在Table2中有相关记录:

B39_a
B39_b
B39_c
B39_d

我要做的就是让Table2中的描述自动获取table1的记录并添加特定的字母。它总是以“a”开头,永远不会达到完整的字母表。

我已经尝试了这个站点的一些代码:http://www.freevbcode.com/ShowCode.asp?ID=5440

  Function IncrementString(ByVal strString As String) As String
  '
  ' Increments a string counter
  ' e.g.  "a" -> "b"
  '             "az" -> "ba"
  '       "zzz" -> "aaaa"
  '
  ' strString is the string to increment, assumed to be lower-case alphabetic
  ' Return value is the incremented string
  '

Dim lngLenString As Long
Dim strChar As String
Dim lngI As Long

lngLenString = Len(strString)

' Start at far right
For lngI = lngLenString To 0 Step -1

' If we reach the far left then add an A and exit
If lngI = 0 Then
   strString = "a" & strString
   Exit For
End If

' Consider next character
strChar = Mid(strString, lngI, 1)
If strChar = "z" Then
  ' If we find Z then increment this to A
  ' and increment the character after this (in next loop iteration)
  strString = Left$(strString, lngI - 1) & "a" & Mid(strString, lngI + 1, lngLenString)
Else
  ' Increment this non-Z and exit
  strString = Left$(strString, lngI - 1) & Chr(Asc(strChar) + 1) & Mid(strString, lngI + 1, lngLenString)
  Exit For
End If

 Next lngI

 IncrementString = strString
 Exit Function

 End Function

显然它没有按应有的方式工作。它增加了字母,但增加了两倍! (i , i , j , j 等)

描述文本框(用于 Table2 Record )具有默认值:

 =IncrementString(DLast("[SeqNo]","[table2]"))

但就像我说的那样,它通过加倍来增加数量。我还必须通过输入“a”来手动启动该过程。

【问题讨论】:

  • 我不会依赖 DLast() 来返回正确的值。记录没有内在的顺序。我输入了“B39_zzz”,函数返回“B39`aaa”。您是否进行过单步调试?
  • 这是一个多用户数据库吗?请注意,如果不立即提交到表,多个用户可能会生成相同的 SeqNo。
  • 这个关系中的主/外键字段是什么? Table2中真的需要重复前缀吗?
  • 这是一个单用户数据库。顺便说一句,它是一个 GeoData 数据库。一个 Record(B39 - main coordiante) 有几个称为 B39_a 等的子坐标... Table2 中有 table1 的外键。所以可以相互关联:
  • 这并没有真正告诉我关键字段是什么。为什么在表 2 中重复 B39?如果没有将 B39_ 前缀作为传递给函数的值的一部分,Lee Mac 的函数将起作用。那么还有其他前缀吗?

标签: ms-access vba


【解决方案1】:

函数和调用代码目前都不允许使用“A##_”前缀。如果您真的必须将此前缀保存到 Table2,则必须调整代码以处理它。照原样,建议不要将“A##”组标识符保存为表 2 中的前缀。使用在 PK/FK 字段上连接表的查询来检索相关数据以进行导出。

DLast() 搜索必须考虑“A##”组标识符,因为每个组都重复该序列。

不幸的是,尝试使用依赖于主表单 ID 的动态参数设置 DefaultValue 属性是不切实际的。一方面,子表单在主表单之前加载,因此无法构建默认值,因为主表单数据和控件不可用。此外,当主窗体移动到新记录时,同样没有用于构建默认值的数据。结果是新记录行上的控件显示错误。

使用 PK/FK 字段进行搜索。

子窗体当前事件中的代码来调用您的递增函数:

If Me.NewRecord And Not IsNull(Me.Parent.ReferenzNR) Then
    Me!SerienBezeichnung = IncrementString(Nz(DLast("SerienBezeichnung", "tbl_GrundminenSerie", "ID_FK=" & Me.Parent.ReferenzID), ""))
End If

请注意,DLast(),即使现在可以工作,最终也可能会失败,因为记录没有固有的顺序。另一种方法可能涉及记录集或嵌套域聚合。在 VBA 即时窗口中测试的示例:
?DMax("SerienBezeichnung","tbl_GrundminenSerie","ID_FK=5 AND Len([SerienBezeichnung])=" & DMax("Len([SerienBezeichnung])","tbl_GrundminenSerie","ID_FK=5"))

或者,如果您觉得自动编号 PK 可以依赖于一直在增加(这一直是我的观察,尽管无法保证自动编号):
?DLookup("SerienBezeichnung","tbl_GrundminenSerie","ID_FK=5 AND SerienID=" & DMax("SerienID","tbl_GrundminenSerie","ID_FK=5"))

【讨论】:

    【解决方案2】:

    考虑以下 VBA 函数:

    Function IncAlpha(ByVal strA As String, ByVal lngI As Long) As String
        If lngI <= 0 Then
            IncAlpha = strA
        ElseIf strA = vbNullString Then
            IncAlpha = IncAlpha("a", lngI - 1)
        Else
            lngI = lngI + Asc(Right(strA, 1)) - 97
            IncAlpha = IncAlpha(Left(strA, Len(strA) - 1), lngI \ 26) & Chr(97 + lngI Mod 26)
        End If
    End Function
    

    提供小写字母字符串,此递归函数将通过提供的长整数参数递增字符串,z 递增到 aaaz 递增到 ba 等等。

    提供空字符串 (""),上述函数将返回 a

    ?IncAlpha("", 1)
    a
    ?IncAlpha("", 26)
    z
    ?IncAlpha("", 27)
    aa
    ?IncAlpha("", 42)
    ap
    ?IncAlpha("", 314159)
    qvsa
    

    使用此函数,后缀可以因此计算使用:

    <prefix> & IncAlpha("", DCount("[SeqNo]","[table2]") + 1)
    

    或者考虑多个前缀:

    <prefix> & IncAlpha("", DCount("SeqNo","table2","SeqNo like '" & <prefix> & "*'") + 1)
    

    【讨论】:

    • 包含“B39_”前缀似乎有意想不到的结果。可能需要调整功能来解决这个问题。我能够使用原始功能做到这一点。
    • @June7 这个函数是为了让 OP 能够为Table2 中的新记录计算适当的后缀——前缀(源自Table1)可以很容易地连接到这样的后缀。跨度>
    • 我知道,但 OP 将 Table2 中的最后一个值作为按顺序生成下一个值的基础。包括前缀。另一个问题:所有记录都具有相同的前缀吗?我猜不是。
    • 好的,它基本上可以工作了。我删除了 DefaultValue 并将我的“B39”文本框(主窗体)连接到我的“B39_A”文本框(子窗体)并输入了此代码 SeqNo.Value = SeqNo.Value + "_" + IncAlpha("", DCount("[SeqNo]", "[table2]") + 1) 。他递增(!)但没有注意前缀。如果有像“B40”这样的新前缀,他必须再次以“a”开头,并且不要继续“B39”行。
    • 需要从表2中提取与主窗体上的前缀关联的最大SeqNo并提取后缀部分。 strSeqNo = Nz(DMax("SeqNo", "Table2", "SeqNo LIKE '" &amp; [Prefix] &amp; "*'"),"") 然后 If InStr(strSeqNo, "_")&gt;0 Then strSeqNo = Mid(strSeqNo, InStr(strSeqNo,"_")+1) 现在将 strSeqNo 传递给递增函数。
    猜你喜欢
    • 1970-01-01
    • 2011-07-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-31
    • 2011-01-04
    相关资源
    最近更新 更多