我正在尝试对现有的Access数据库应用程序进行故障排除,该应用程序应该生成介于1和表中记录数之间的随机数。这是针对具有不同记录数量的2个不同表格完成的。记录较少的表显示了应该显示的10个重复数字,并写入单独的表。我假设较大的表会发生同样的情况,但有更多数字可供选择,我只是无法复制问题。
以下是删除错误处理的代码示例:
Dim db As DAO.Database
Dim rstRecords As DAO.Recordset
Dim rs As DAO.Recordset
Dim tdfNew As TableDef
Dim fldNew As Field
Dim i As Integer
Dim K As Integer
Dim Check As String
Set db = CurrentDb
Set rstRecords = db.OpenRecordset("customer_table")
rstRecords.MoveLast
FindRecordCount = rstRecords.RecordCount
i = rstRecords.RecordCount
DoCmd.DeleteObject acTable, "Unique_numbers"
'--- create the table
Set tdfNew = db.CreateTableDef("Unique_numbers")
'--- add text field (length 20)
Set fldNew = tdfNew.CreateField("customer_table", dbLong)
'--- save the new field
tdfNew.Fields.Append fldNew
'--- save the new table design
db.TableDefs.Append tdfNew
'---Initialize your recordset
Set rs = CurrentDb.OpenRecordset("Unique_numbers", dbOpenDynaset)
'Dim i As Integer
'Dim K As Integer
'Dim Check As String
'i = TxtInput
TxtInput = i
K = 0
Check = T
Do
Do While K < 11
'K = K + 1
Randomize
If K = 0 Then
TxtOutput = Fix(i * Rnd) + 1
rs.AddNew
rs.Fields(0).Value = TxtOutput
rs.Update
K = K + 1
ElseIf K = 1 Then
TxtOutput2 = Fix(i * Rnd) + 1
rs.AddNew
rs.Fields(0).Value = TxtOutput2
rs.Update
K = K + 1
ElseIf K = 2 Then
TxtOutput3 = Fix(i * Rnd) + 1
rs.AddNew
rs.Fields(0).Value = TxtOutput3
rs.Update
K = K + 1
ElseIf K = 3 Then
TxtOutput4 = Fix(i * Rnd) + 1
rs.AddNew
rs.Fields(0).Value = TxtOutput4
rs.Update
K = K + 1
ElseIf K = 4 Then
TxtOutput5 = Fix(i * Rnd) + 1
rs.AddNew
rs.Fields(0).Value = TxtOutput5
rs.Update
K = K + 1
ElseIf K = 5 Then
TxtOutput6 = Fix(i * Rnd) + 1
rs.AddNew
rs.Fields(0).Value = TxtOutput6
rs.Update
K = K + 1
ElseIf K = 6 Then
TxtOutput7 = Fix(i * Rnd) + 1
rs.AddNew
rs.Fields(0).Value = TxtOutput7
rs.Update
K = K + 1
ElseIf K = 7 Then
TxtOutput8 = Fix(i * Rnd) + 1
rs.AddNew
rs.Fields(0).Value = TxtOutput8
rs.Update
K = K + 1
ElseIf K = 8 Then
TxtOutput9 = Fix(i * Rnd) + 1
rs.AddNew
rs.Fields(0).Value = TxtOutput9
rs.Update
K = K + 1
ElseIf K = 9 Then
TxtOutput10 = Fix(i * Rnd) + 1
rs.AddNew
rs.Fields(0).Value = TxtOutput10
rs.Update
K = K + 1
Check = f
Exit Do
End If
Loop
Loop Until Check = f
答案 0 :(得分:1)
请注意,Randomize VBA函数会重新初始化随机数生成器种子。没有arugments,它使用系统计时器作为种子。
在每次调用Rnd之前,每次循环迭代都会重新初始化它。鉴于调用Randomize之间可能没有太多时间,您可能会在同一点重复重新启动随机数生成器,从而导致重复的数字。
尝试在代码顶部调用一次Randomize。
答案 1 :(得分:0)
生成随机数不是问题。生成随机唯一编号也不是问题。但是,从一个范围中选择一个尚未选择的随机数需要跟踪使用过的数字。问题在于性能,特别是如果您想从表中读取/更新值并检查ID是否已被使用。
您有两种选择。 (也许更多,我现在无法想到)
第一种方法看起来像这样: 您可以从范围中发送最小值和最大值,并获取尚未使用的值。阵列或持有人将用于跟踪您使用和未使用的号码。我使用字典但你可以使用数组或数组与字典。
SELECT wp_posts. * ,
SUM( wp_wti_like_post.value ) -4 AS total_sum,
wp_wti_like_post.post_id
FROM wp_posts
INNER JOIN wp_term_relationships ON ( wp_posts.ID =
wp_term_relationships.object_id )
INNER JOIN wp_term_taxonomy ON ( wp_term_relationships.term_taxonomy_id =
wp_term_taxonomy.term_taxonomy_id )
JOIN wp_postmeta ON ( wp_posts.ID = wp_postmeta.post_id )
LEFT JOIN wp_wti_like_post ON ( wp_posts.ID = wp_wti_like_post.post_id )
WHERE wp_term_taxonomy.taxonomy = 'category'
AND wp_term_taxonomy.term_id IN ('$c_cid')
AND wp_posts.post_type = 'post'
AND (wp_posts.post_status = 'publish')
GROUP BY wp_posts.ID
HAVING SUM( wp_wti_like_post.value ) > $min_like
ORDER BY wp_posts.post_date DESC
只需通过以下方式从您的范围中获取随机唯一ID:
Option Compare Database
Option Explicit
Private mNumbers As Object
Private mSession_ID As Long
Public Function FN_GET_RANDOM_NO(iMin As Long, iMax As Long) As Long
FN_GET_RANDOM_NO = Int((iMax - iMin + 1) * Rnd + iMin)
End Function
Public Function FN_RANDOM_INIT_COLLECTION(iSession_id As Long, iMin As Long, iMax As Long) As Object
Set mNumbers = CreateObject("Scripting.Dictionary")
Dim i, J As Long
mSession_ID = iSession_id
J = 0
For i = iMin To iMax
J = J + 1
mNumbers.Add J, i
Next i
End Function
Public Function FN_RANDOM_READ_UNUSED_NO() As Long
Dim ID As Long
ID = FN_GET_RANDOM_NO(1, mNumbers.count)
FN_RANDOM_READ_UNUSED_NO = mNumbers(ID)
If mNumbers.exists(ID) Then mNumbers.Remove ID
Dim tmpDic As Object
Set tmpDic = CreateObject("Scripting.Dictionary")
Dim item As Variant
Dim i As Long
i = 0
For Each item In mNumbers
i = i + 1
tmpDic.Add i, mNumbers(item)
Next item
Set mNumbers = tmpDic
End Function
Public Function FN_GET_UNUSED_NO(iSession_id As Long, iMin As Long, iMax As Long) As Long
If mSession_ID = iSession_id Then
If Not mNumbers Is Nothing Then
READ_AFTER:
FN_GET_UNUSED_NO = FN_RANDOM_READ_UNUSED_NO
Else
INIT:
'initialize the table
FN_RANDOM_INIT_COLLECTION iSession_id, iMin, iMax
GoTo READ_AFTER:
End If
Else
'new session reload the used number collection
Set mNumbers = Nothing
GoTo INIT
End If
End Function
session_id用于标识您在一个会话中访问该集合。不同的id会重新初始化未使用的表。如果要管理多个集合,请展开代码。也许有阵列。
如果还没有要返回的数字,它将返回0。
结果将如下所示:
FN_GET_UNUSED_NO(1,10, 50)
第二种方法非常简单,您只需检索一个随机值,检查该值是否已在新表中分配。