業務部門臨時需求:現有抽獎軟體單次僅抽一號碼,但本次 500 個中獎名額需逐一點擊記錄,耗時易錯。限期半天,隔天即用。作者果斷選擇 Excel VBA,兩小時完工交付。

' 資料來源工作表欄位
Const START_ROW_SOURCE As Integer = 2
Const ID_SOURCE As String = "B"
Const RESULT_SOURCE As String = "C"
' 結果工作表欄位
Const ID_RESULT As String = "B"
Const FIRST_CELL_RESULT As String = "B5"
Const START_ROW_RESULT As Integer = 5
Private maxRow_Source As Integer
Private Sub cmdDraw_Click()
On Error GoTo ErrorHandler
Dim rewardLevel As String: rewardLevel = txtLevel.Text
Dim rewardCount As Integer
If Trim(txtCount.Text) <> "" Then rewardCount = CInt(txtCount.Text) Else { MsgBox "請輸入中獎人數!"; Exit Sub }
maxRow_Source = getMaxRow(shtDataSource)
' 清除舊結果
Dim maxRow_result As Integer: maxRow_result = getMaxRow(shtDrawResult)
If maxRow_result > START_ROW_RESULT Then
shtDrawResult.Range(FIRST_CELL_RESULT, shtDrawResult.Cells.SpecialCells(xlCellTypeLastCell)).Value = ""
End If
Dim drewCount As Integer = 0, curResultRow As Integer = START_ROW_RESULT
Dim randomRow As Integer, currentID As String, currentRewardStatus As String
' 循環抽取指定數量
While drewCount < rewardCount
randomRow = (maxRow_Source - START_ROW_SOURCE + 1) * Rnd + START_ROW_SOURCE
currentID = shtDataSource.Range(ID_SOURCE & CStr(randomRow)).Cells.Value
If Trim(currentID) <> "" Then
currentRewardStatus = shtDataSource.Range(RESULT_SOURCE & CStr(randomRow)).Cells.Value
If Trim(currentRewardStatus) = "" Then
' 複製到結果表
shtDataSource.Range(ID_SOURCE & CStr(randomRow)).Copy
shtDrawResult.Range(ID_RESULT & CStr(curResultRow)).PasteSpecial xlPasteAll
' 標記已中獎
shtDataSource.Range(RESULT_SOURCE & CStr(randomRow)).Cells.Value = rewardLevel
curResultRow = curResultRow + 1
End If
End If
drewCount = drewCount + 1
Wend
GoTo ExitHandler
ErrorHandler: MsgBox "出現問題!": Exit Sub
ExitHandler: MsgBox "完成!"
End Sub
Function getMaxRow(sht As Worksheet) As Integer
Dim lastCell As Range: Set lastCell = sht.Cells.SpecialCells(xlCellTypeLastCell)
getMaxRow = lastCell.Row
End Function
Rnd 產生隨機行號RESULT_SOURCE 欄位是否為空,避免重複中獎此經驗分享給所有面對臨時性、資料導向業務需求的開發者。