VBA固定溢出行
我是VBA的新手。我正在处理一个循环和创建一个句子的问题,但是我遇到了一个行溢出的问题。你能解释一下我哪里出错了吗VBA固定溢出行,vba,Vba,我是VBA的新手。我正在处理一个循环和创建一个句子的问题,但是我遇到了一个行溢出的问题。你能解释一下我哪里出错了吗 Sub clue() Dim name, room, weapon As String Dim can, dag, lead, rev, rop, wre, total, least As Double Dim row As Integer Cells(1, 1).Activate cam = 0 dag = 0 lead = 0 rev = 0 rop = 0 wre = 0
Sub clue()
Dim name, room, weapon As String
Dim can, dag, lead, rev, rop, wre, total, least As Double
Dim row As Integer
Cells(1, 1).Activate
cam = 0
dag = 0
lead = 0
rev = 0
rop = 0
wre = 0
row = 1
Do Until IsEmpty(ActiveCell)
name = ActiveCell.Value
room = ActiveCell.Offset(1, 0).Value
weapon = ActiveCell.Offset(2, 0).Value
Cells(row, 3).Value = name & " in the " & room & " with the " & weapon & "."
If weapon = "Candlestick" Then
can = can + 1
End If
If weapon = "Dagger" Then
dag = dag + 1
End If
If weapon = "Lead Pipe" Then
lead = lead + 1
End If
If weapon = "Revolver" Then
rev = rev + 1
End If
If weapon = "Rope" Then
rop = rop + 1
End If
If weapon = "Wrench" Then
wre = wre + 1
End If
ActiveCell.End(xlDown).End(xlDown).Activate
row = row + 1
Loop
total = can + dag + lead + rev + rop + wre
Cells(2, 6) = can
Cells(3, 6) = dag
Cells(4, 6) = lead
Cells(5, 6) = rev
Cells(6, 6) = rop
Cells(7, 6) = wre
Cells(2, 7) = can / total
Cells(3, 7) = dag / total
Cells(4, 7) = lead / total
Cells(5, 7) = rev / total
Cells(6, 7) = rop / total
Cells(7, 7) = wre / total
least = 1000000000
If can < least Then least = can
If dag < can Then least = dag
If lead < dag Then least = lead
If rev < lead Then least = rev
If rop < rev Then least = rop
If wre < rop Then least = wre
Cells(10, 5) = least
End Sub
子线索()
模糊的名字、房间、武器
Dim can、dag、导线、转速、rop、wre、总计,至少为双精度
将行设置为整数
细胞(1,1)。激活
凸轮=0
dag=0
领先=0
rev=0
rop=0
wre=0
行=1
直到IsEmpty(ActiveCell)为止
name=ActiveCell.Value
room=ActiveCell.Offset(1,0).Value
武器=活动单元。偏移量(2,0)。值
单元格(第3行)。Value=name&“在带有“&武器&”的“&房间&”中
如果武器=“烛台”,则
can=can+1
如果结束
如果武器=“匕首”,则
dag=dag+1
如果结束
如果武器=“铅管”,则
铅=铅+1
如果结束
如果武器=“左轮手枪”,则
rev=rev+1
如果结束
如果武器=“绳索”,则
机械钻速=机械钻速+1
如果结束
如果武器=“扳手”,则
wre=wre+1
如果结束
ActiveCell.End(xlDown).End(xlDown.Activate
行=行+1
环
总计=can+dag+导线+rev+rop+wre
单元(2,6)=can
单元(3,6)=dag
电池(4,6)=铅
单元格(5,6)=修订版
单元(6,6)=rop
单元(7,6)=wre
单元格(2,7)=罐/总罐
单元格(3,7)=dag/总数
单元(4,7)=铅/总
单元格(5,7)=修订/总计
单元格(6,7)=rop/总计
单元格(7,7)=wre/总数
至少=100000000
如果can<最小值,则最小值=can
如果dag
我试图使用某些输入在一行上打印一个句子,但随着输入的变化,我想在下一行上打印下一个句子(因此,行=行+1),但它一直说存在“溢出”问题,我需要更改一些内容,但我不知道为什么。有人知道吗
谢谢 一旦读取了32K行,可能会出现溢出 这是因为您将
行
变量声明为整数
将其更改为long
,您将能够处理20亿行
Dim row As Long
请记住这一点:
Byte between 0 and 255.
Integer between -32,768 and 32,767.
Long between – 2,147,483,648 and 2,147,483,647.
Currency between -922,337,203,685,477.5808 and 922,337,203’685,477.5807.
Single between -3.402823E38 and 3.402823E38.
Double between -1.79769313486232D308 and 1.79769313486232D308.
行
返回一个长
,而不是整数
注意
以字符串形式显示姓名、房间、武器
仅将
武器
定义为字符串
,其余为变体
正确的语法是
Dim name as string,room as string,willer as string
我喜欢这个“游戏”式的问题,而且,既然你宣称自己是“VBA的新手”,我认为它可以帮助你对初始代码进行以下重构
Option Explicit
Sub clue()
Dim can As Long, dag As Long, lead As Long, rev As Long, rop As Long, wre As Long, row As Long
Dim weapon As String
Dim roomsRng As Range, areaRng As Range, roomsReportRng As Range, finalStatsRng As Range, leastStatsRng As Range ' these are useful range variable. you'll set them and use to avoid loosing control over what you're actually handling
' here follows a section dedicated to setting relevant "ranges". this helps a lot in avoiding loosing control over what you're actually handling
With ActiveSheet 'always explicitly qualify which worksheet do you want to work with. "ActiveSheet" is the currently active one, but you may want to qualify 'Worksheets("MySheetName")'
Set roomsRng = .Range("A1:A" & .cells(.Rows.Count, 1).End(xlUp).row) 'set roomsRng range as the one collecting activesheet cells in column "A" down to the last non empty one
Set roomsRng = roomsRng.SpecialCells(xlCellTypeConstants, xlTextValues) 'select only non blank cells of "roomsRng" range (skip blanks)
Set roomsReportRng = .cells(1, 3) ' set the range you start writing rooms report from
Set finalStatsRng = .Range("F2") ' set the range you'll start writing final stats from
Set leastStatsRng = .Range("E10") ' set the range you'll write the least found weapon number in
End With
For Each areaRng In roomsRng.Areas 'loop through all "Areas" of "roomsRng" range cells: an "Area" is a group of contiguous cells
Call WriteRoomsReport(areaRng.cells, roomsReportRng, row, weapon) 'write room report
Call UpdateWeaponsStats(weapon, can, dag, lead, rev, rop, wre) ' update weapons statistics
Next areaRng
Call WriteFinalStats(can, dag, lead, rev, rop, wre, finalStatsRng, leastStatsRng) ' write final statistics
End Sub
Sub WriteRoomsReport(roomCells As Range, reportCell As Range, row As Long, weapon As String)
Dim arr As Variant 'it'll be used as an array, see below
arr = Application.Transpose(roomCells) 'initialize the Variant as an array, filling it up with "roomCells" range content
reportCell.Offset(row).Value = arr(1) & " in the " & arr(2) & " with the " & arr(3) & "." 'write the report line
weapon = arr(3) ' store the weapon value to pass back to calling sub
row = row + 1 'update the row for subsequent use
End Sub
Sub UpdateWeaponsStats(weapon As String, can As Long, dag As Long, lead As Long, rev As Long, rop As Long, wre As Long)
' use "Select Case" pattern to avoid multiple and unuesful If-then repetition
' once a "case" is hit, its correspondant statements will be processed and then control passes to the statement following the "End Select" one
Select Case weapon
Case "Candlestick"
can = can + 1
Case Is = "Dagger"
dag = dag + 1
Case "Lead Pipe"
lead = lead + 1
Case Is = "Revolver"
rev = rev + 1
Case "Rope"
rop = rop + 1
Case Is = "Wrench"
wre = wre + 1
End Select
End Sub
Sub WriteFinalStats(can As Long, dag As Long, lead As Long, rev As Long, rop As Long, wre As Long, finalStatsRng As Range, leastStatsRng As Range)
Dim total As Long, least As Long
Dim weaponArr As Variant
total = can + dag + lead + rev + rop + wre
weaponArr = Array(can, dag, lead, rev, rop, wre)
With finalStatsRng.Resize(6) ' select a range of 6 cells in one clolumn, starting from the passed "finalStatsRng" range and resizing it up to enclose the subsequent 5 cells below it
.Value = Application.Transpose(weaponArr) ' fill the selected range (using ".Value" property of the "Range" object) with the "array" technique
With .Offset(, 1) ' shift one column to the right of selected range
.FormulaR1C1 = "=RC[-1]/" & total ' write in all cells a formula that takes the value form the adjacent cell and divide it by the "total" variable value
.Value = .Value ' have formulas replaced with values. you can comment this and cells will remain with formulas (they show the resulting values, but if you select one of them you'll see a formula in the formula ribbon of Excel UI
End With
End With
leastStatsRng.Value = Application.WorksheetFunction.Min(weaponArr) 'get the minimum value of all passed values calling the "MIN" function (which belongs to "WorksheetFuncion" object of the "Application" object -Excel) over the array filled with weapon countings
End Sub
上述代码模式具有以下目的:
- 将代码分解为特定的函数或子函数 通过“main”子语句(应该是一系列语句,如“Call DoThis()”、“Call DoThat()”、…)可以更好地控制代码流,并将精力集中在处理特定作业的特定子语句/函数上 从而产生一个更易于维护和“调试”的代码
- 只使用一些(众多)相关的VBA和Excel VBA技术,如使用
范围
对象(请参见
,调整大小()
,偏移量()
,结束()
方法),数组(通过特殊单元格()
变量
类型变量),
对象 当然,您需要学习所有这些技术(以及许多其他技术!),利用诸如SO本身、MSDN site()等资源,以及通过谷歌搜索一个重要问题就可以在web上轻松找到的许多其他资源工作表函数
如果“构建游戏”是您真正的目标,那么您最好立即切换到一些真正的OOP语言,如C#,以及相应的IDE,如Visual Studio(其社区版目前是免费的)将行定义为长数据类型
Dim row as Long
将解决此问题。在模块的最顶端添加选项Explicit
-您已将can
声明为变量,并将值设置为cam
。