如果/ Else GoTo VBA Excel

时间:2014-01-06 18:56:45

标签: excel vba excel-vba

VBA很新。试图搜索无济于事。我有以下代码:

monsterRollingForHit: rollForMonsterHit = (Int(2 * Rnd))
MsgBox rollForMonsterHit, 0, "Monster Hit Roll"
If rollForMonsterHit = 1 Then
    GoTo monsterRollingForDmg
Else
    GoTo playerRollingForHit
End If

'if monster hits we then roll for his base damage
'using a working around for randBetween due to Analysis Toolpak being required for that     function
monsterRollingForDmg: rollForMonsterDmg = ((Int((6 * Rnd) + 1)))
MsgBox rollForMonsterDmg, 0, "Monster Dmg Roll"
GoTo monsterRollingForCrit

'we then add crit if the monster critically hits
monsterRollingForCrit: rollForMonsterCrit = (rollForMonsterDmg + ((Int(2 * Rnd)) * 8))
MsgBox rollForMonsterCrit, 0, "Monster Crit Roll"
GoTo rollingForPlayerArmor

'finally we reduce the monster's dmg with potential crit by the player's armor
rollingForPlayerArmor: finalMonsterDmg = (rollForMonsterCrit * (((Int((26 * Rnd) + 75)))     / 100))
MsgBox finalMonsterDmg, 0, "Monster Final Dmg"
GoTo reducePlayerHealth

reducePlayerHealth: currentPlayerHP = (currentPlayerHP - finalMonsterDmg)
MsgBox currentPlayerHP, 0, "Current Player HP"
If currentPlayerHP > 0 Then
    GoTo playerRollingForHit
Else
    MsgBox "Monster Wins"
    Exit Sub
End If

问题是即使rollForMonsterHit值为0,它也永远不会转到playerRollingForHit。相反,它只是滚动,直到它得到1,然后继续。

问题:需要跳过Else条件的代码体

4 个答案:

答案 0 :(得分:3)

使用Option Explicit有助于查找变量名称中的拼写错误。

这将是你似乎正在尝试的伪代码。还注意到没有goto或标签。

Set MonsterHP and HeroHP
while monsterHP>0 and HeroHP>0
    if MonsterHit then
        work out monsterdmg
        decide if critical
        deduct from heroHP, accounting for any armor/dodge/etc
    endif
    if HeroHit then
        work out HeroDmg
        decide if critical
        deduct from MonsterHP, accounting for any armor/dodge/etc
    endif
wend
if monsterdmg>0 then
    print "Monster Wins"
elseif heroHP>0 then
    print "Hero wins"
else
    print "They killed each other with their final blow!"
endif

答案 1 :(得分:1)

您没有定义标签playerRollingForHit ...至少在您显示的代码中没有。这是一个问题。

正如其他人所指出的,不了解代码结构是一个更大的问题。 GoTo声明虽然合法,但应谨慎使用。您应该考虑使您的代码更易于重用。例如,您可以创建自己的数据类型:

Public Type player
  health As Integer
  strength As Integer
  ' whatever other properties you might have...
End Type

然后你可以创建一系列玩家:

Dim players( 1 To 2 ) as player

这意味着你将能够循环播放器,“玩家1攻击玩家2”可以使用与“玩家2攻击玩家1”相同的代码(如果他们有相同的规则)。同样,您可能想要创建自己的“rollBetween”函数,它允许您使用简单的指令滚动不同的骰子。

Function rollBetween(n1 As Integer, n2 As Integer)
' roll a number between n1 and n2, inclusive
rollBetween = Round(Rnd * (n2 - n1 + 1) - 0.5, 0) + n1
End Function

把它们放在一起,为了好玩,我创建了一些代码,可以帮助你理解我在说什么。注意 - 这里的规则与您使用的规则不同,但原则相同;随着玩家获得更多力量,他们对攻击变得更加自由,并且他们的攻击变得更强大。我希望你能从中学到一些东西,并且玩得开心!

Option Explicit

Public Type player
  health As Integer
  strength As Integer
End Type

Sub monsters()
' main program loop
' can have more than two players: just change dimension of array
' and rules of "who attacks whom"
Dim players(1 To 2) As player
Dim attacker As Integer
Dim defender As Integer

initPlayers players
attacker = rollBetween(1, 2) ' who goes first: player 1 or 2
Debug.Print "Player " & attacker & " gets the first roll"

While stillAlive(players)
  defender = (attacker Mod 2) + 1
  playTurn players, attacker, defender
  attacker = defender  ' person who was attacked becomes the attacker
Wend

MsgBox winner(players())

End Sub

'------------------------------
' functions that support the main program loop 'monsters':

Function rollBetween(n1 As Integer, n2 As Integer)
' roll a number between n1 and n2, inclusive
rollBetween = Round(Rnd * (n2 - n1 + 1) - 0.5, 0) + n1
End Function

Sub initPlayers(ByRef p() As player)
' initialize the strength of the players etc
Dim ii
For ii = LBound(p) To UBound(p)
  p(ii).health = 10
  p(ii).strength = 1
Next

End Sub

Function stillAlive(p() As player) As Boolean
' see whether players are still alive
' returns false if at least one player's health is less than 0
Dim ii
For ii = LBound(p) To UBound(p)
  If p(ii).health <= 0 Then
    stillAlive = False
    Exit Function
  End If
Next ii
stillAlive = True
End Function

Sub playTurn(ByRef p() As player, n As Integer, m As Integer)
' attack of player(n) on player(m)
Dim roll As Integer

' see if you can attack, or just heal:
roll = rollBetween(1, 2)
Debug.Print "player " & n & " rolled a " & roll

If roll = 1 Then
  ' roll for damage
  roll = rollBetween(1, 4 + p(n).strength)  ' as he gets stronger, attacks become more damaging
  Debug.Print "player " & n & " rolled a " & roll & " for attack"
  If p(m).strength > roll Then
    p(n).strength = p(n).strength - 1 ' attacker gets weaker because attack failed
    p(m).strength = p(m).strength + 2 ' defender gets stronger
  Else
    p(n).strength = p(n).strength + 1 ' attacker gains strength
    p(m).health = p(m).health - roll  ' defender loses health
  End If
Else
  ' roll for healing
  roll = rollBetween(1, 3)
  Debug.Print "player " & n & " rolled a " & roll & " for health"
  p(n).health = p(n).health + roll
End If
Debug.Print "statistics now: " & p(1).health & "," & p(1).strength & ";" & p(2).health & "," & p(2).strength

End Sub

Function winner(p() As player)
Dim ii, h, w
' track player with higher health:
h = 0
w = 0

For ii = LBound(p) To UBound(p)
  If p(ii).health > h Then
    w = ii
    h = p(ii).health
  End If
Next ii

winner = "Player " & w & " is the winner!"

End Function

典型游戏的输出可能是:

Player 2 gets the first roll
player 2 rolled a 2
player 2 rolled a 2 for health
statistics now: 10,1;12,1
player 1 rolled a 1
player 1 rolled a 2 for attack
statistics now: 10,2;10,1
player 2 rolled a 2
player 2 rolled a 1 for health
statistics now: 10,2;11,1
player 1 rolled a 2
player 1 rolled a 3 for health
statistics now: 13,2;11,1
player 2 rolled a 2
player 2 rolled a 1 for health
statistics now: 13,2;12,1
player 1 rolled a 1
player 1 rolled a 6 for attack
statistics now: 13,3;6,1
player 2 rolled a 2
player 2 rolled a 2 for health
statistics now: 13,3;8,1
player 1 rolled a 2
player 1 rolled a 3 for health
statistics now: 16,3;8,1
player 2 rolled a 1
player 2 rolled a 5 for attack
statistics now: 11,3;8,2
player 1 rolled a 1
player 1 rolled a 4 for attack
statistics now: 11,4;4,2
player 2 rolled a 2
player 2 rolled a 1 for health
statistics now: 11,4;5,2
player 1 rolled a 2
player 1 rolled a 2 for health
statistics now: 13,4;5,2
player 2 rolled a 1
player 2 rolled a 4 for attack
statistics now: 9,4;5,3
player 1 rolled a 2
player 1 rolled a 1 for health
statistics now: 10,4;5,3
player 2 rolled a 1
player 2 rolled a 6 for attack
statistics now: 4,4;5,4
player 1 rolled a 2
player 1 rolled a 2 for health
statistics now: 6,4;5,4
player 2 rolled a 2
player 2 rolled a 3 for health
statistics now: 6,4;8,4
player 1 rolled a 1
player 1 rolled a 6 for attack
statistics now: 6,5;2,4
player 2 rolled a 2
player 2 rolled a 1 for health
statistics now: 6,5;3,4
player 1 rolled a 2
player 1 rolled a 1 for health
statistics now: 7,5;3,4
player 2 rolled a 2
player 2 rolled a 3 for health
statistics now: 7,5;6,4
player 1 rolled a 1
player 1 rolled a 6 for attack
statistics now: 7,6;0,4

最终输出 - 声明玩家1获胜者的消息框。

答案 2 :(得分:-1)

请改为:monsterRollingForHit: rollForMonsterHit = Application.WorksheetFunction.RoundDown(2 * Rnd(), 0)

答案 3 :(得分:-3)

For i = 1 To ActiveWorkbook.Worksheets.Count
  If Worksheets(i).Name = "Table B" Or Worksheets(i).Name = "Table C" Then GoTo line1
  If Worksheets(i).Name = "Table N" Then GoTo line3
  If Worksheets(i).Name = "Table O" Then GoTo line2
Next i