Funktion gibt sporadisch #WERT! zurück

Informationen und Beispiele zu den hier genannten Dialog-Elementen:
MsgBox
Bild

Betrifft: Funktion gibt sporadisch #WERT! zurück
von: Manne
Geschrieben am: 07.06.2015 15:23:45

Hallo schon wieder,
ich habe eine Funktion geschrieben, die grundsätzlich funktioniert, Aber sporadisch ein #WERT! ausgibt, ohne das sich an der Funktion oder den Zellen irgendetwas ändert.
Das geschieht indem ich z.B. eine SUB ausführe, welche nichts auf dem Sheet ändert auf dem die Funktion ihre Daten sammelt.
Hier mal die Funktion:

Function fCreateWiki(Tier As Byte, BR As Single, _
                     fType, Tank, Gun, VisDiscrepancy As String, _
                     FullAmmo As Integer, _
                     EmptyRacks As Range, _
                     Recom, Comment, ImageName, WikiName As String, _
                     Colspan As Integer) As String
'Application.Volatile
'Dimensions
Dim ii, bold, ital, rs, cs, se As String
Dim WikiText, fText, fName As String
Dim rng As Range
'Dim fZahl As Single
'Values
ii = " || "
bold = "'''"
ital = "''"
rs = "rowspan=" & Chr(34)
cs = "colspan=" & Chr(34)
se = Chr(34) & "|"
            'Start creating Wiki !!!
'Start
WikiText = "| "
'Tier
If Colspan = 1 Then
    fText = "T" & Tier & ii
ElseIf Colspan >= 2 Then
    fText = rs & Colspan & se & "T" & Tier & ii
Else '0
    fText = ""
End If
WikiText = WikiText & fText
'BR (Nachkommastelle erzwingen und . statt ,)
BR = BR * 10
If Colspan = 1 Then
    fText = Left(BR, 1) & "." & Right(BR, 1) & ii
ElseIf Colspan >= 2 Then
    fText = rs & Colspan & se & Left(BR, 1) & "." & Right(BR, 1) & ii
Else '0
    fText = ""
End If
'fText = Replace(fText, ",", ".")
WikiText = WikiText & fText
'Type
If Colspan = 1 Then
    fText = fType & ii
ElseIf Colspan >= 2 Then
    fText = rs & Colspan & se & fType & ii
Else '0
    fText = ""
End If
WikiText = WikiText & fText
'Name
If WikiName <> "" Then
    If Tank = WikiName Then
        fName = bold & "[[" & WikiName & "]]" & bold
    Else
        Tank = Replace(Tank, " ", " ")
        fName = bold & "[[" & WikiName & "|" & Tank & "]]" & bold
    End If
End If
If Colspan = 1 Then
    fText = cs & 2 & se & fName & ii
ElseIf Colspan >= 2 Then
    fText = rs & Colspan & se & fName & ii
Else '0
    fText = ""
End If
WikiText = WikiText & fText
'Gun
If Gun <> "" Then
    fText = ital & Gun & ital & ii
Else '0
    fText = ""
End If
WikiText = WikiText & fText
'Full ammo
If Gun = "Projectiles" Then
    fText = rs & 2 & se & bold & FullAmmo & bold & ii
ElseIf Gun = "Propellants" Then
    fText = ""
Else
    fText = bold & FullAmmo & bold & ii
End If
WikiText = WikiText & fText
'EmptyRacks
fText = ""
For Each rng In EmptyRacks
    If rng.Text <> "" Then
        fText = fText & rng.Text & " (+" & FullAmmo - rng.Text & ")" & ii
    Else '0
        fText = fText & ii
    End If
Next
WikiText = WikiText & fText
'Visual discrepancy
fText = VisDiscrepancy & ii
WikiText = WikiText & fText
'Recommendations
If Gun = "Projectiles" Then
    fText = rs & 2 & se & Recom & ii
ElseIf Gun = "Propellants" Then
    fText = ""
Else
    fText = Recom & ii
End If
fText = Replace(fText, " (+", " (+")
WikiText = WikiText + fText
'Comments
fText = Comment
WikiText = WikiText & fText
'Images
If Colspan = 1 Then
    fText = ii & "[[media:Ammoracks " & ImageName & ".png|Image]]"
ElseIf Colspan >= 2 Then
    fText = ii & rs & Colspan & se & "[[media:Ammoracks " & ImageName & ".png|Image]]"
Else
    fText = ""
End If
WikiText = WikiText & fText
'End
'Debug.Print WikiText
fCreateWiki = WikiText
End Function
Hier die SUB, welches sporadisch die Funktion stört:
Sub CreateWiki()
Dim i, j, intAnfang, intEnde As Integer
Dim strNation As String
'Daten erheben
intAnfang = 5
intEnde = 200
strNation = Range("FilterNation")
'Sheet bereinigen
Worksheets("Wiki").Range("A:A").Clear
'Wiki Text erstellen
j = 1
For i = intAnfang To intEnde
    If Worksheets("Input").Range("A" & i) = strNation Then
        strString = Worksheets("Input").Range("AB" & i)
        Worksheets("Wiki").Range("A" & j) = strString
        j = j + 1
        Worksheets("Wiki").Range("A" & j) = "|-"
        j = j + 1
    End If
Next i
'Zum Copy&Pasten auswählen
j = j - 1
Sheets("Wiki").Select
Range("A1:A" & j).Select
Selection.Copy
Sheets("Input").Select
End Sub
Das gesammte Workbook besteht aus zwei Sheets.
Auf dem Sheet 1 "Input" befinden sich Daten im Bereich A5:X160. In den Zellen AB5:AB160 befindet sich die fCreateWiki Funktionen:
=fCreateWiki(C5;D5;E5;F5;G5;H5;I5;J5:S5;T5;U5;V5;W5;X5)
Die SUB CreateWiki liest dann nochmals die Daten aus AB5:AB160 und schreibt sie in das Sheet 2 "Wiki".
Zu Beginn hatte ich in der Funktion noch Application.Volatile aktiv um eine Neuberechnung mit F9 erzwingen zu können. Dies führt bei der SUB allerdings dazu, daß es zu einer erheblichen Wartezeit kommt und die erste Zelle auf Sheet 2 #WERT! zugewiesen bekommt.
Ohne Application.Volatile wird es korrekt übertragen, aber sporadisch ändert sich dann die Ausgabe der Funktion auf #WERT! in AB5:AB160 vor dem Abarbeiten der SUB.
Da ich auf F9 verzichten muss habe ich ein Makro erstellt, welches mir das manuelle Aktualisieren erspart.
Sub FunktionAktualisieren()
    Range("AB4").Select
    Selection.AutoFill Destination:=Range("AB4:AB160"), Type:=xlFillDefault
    Range("AB4:AB160").Select
End Sub

Dieses führt aber 100%ig dazu, daß die Funktion #WERT! ausgibt. Führe ich das Autobefüllen von Hand aus, funktioniert es allerdings problemlos.
fCreateWiki und CreateWiki befinden sich beide im selben Modul.
Was mache ich falsch?
Gruß,
Manne

Bild

Betrifft: AW: Funktion gibt sporadisch #WERT! zurück
von: Mullit
Geschrieben am: 07.06.2015 17:28:31
Hallo,
zunächst nur zwei allgemeine Hinweise: bei dieser Variablenmenge (wenn nicht immer) würde ich zwingend Option Explicit verwenden und Deine Variablen sind nicht eindeutig deklariert: Nur die letzte Variable ist bei Deiner Art der Deklaration vom jeweiligen angegebenen Typ die anderen sind vom Typ Variant, d.h. Du mußt jeder Variablen explicit ihren Typ zuweisen, andernfalls steigt die Fehleranfälligkeit:

Dim ii As String, bold As String, ital As String, rs As String, cs As String, se As String

Wahrscheinlich ist der Fehler damit allerdings noch nicht behoben...
Gruß, Mullit

Bild

Betrifft: AW: Funktion gibt sporadisch #WERT! zurück
von: Mullit
Geschrieben am: 07.06.2015 20:39:46
Hallo,
mal etwas ins Blaue: Du scheinst an der unten aufgezeigten Stelle mit Zahlenwerten zu operieren, verwendest aber in Deinem Code die .Text-Eigenschaft, das wirft den Wert-Fehler, bei Verwendung der .Value-Eigenschaft läuft der Code durch.

'EmptyRacks
fText = ""
For Each rng In EmptyRacks
    If rng.Value <> "" Then
        fText = fText & rng.Value & " (+" & FullAmmo - rng.Value & ")" & ii
    Else '0
        fText = fText & ii
    End If
Next
WikiText = WikiText & fText

Gruß, Mullit

Bild

Betrifft: AW: Funktion gibt sporadisch #WERT! zurück
von: Mullit
Geschrieben am: 07.06.2015 21:39:14
Hallo,
für Härtefälle kannst Du Dir übrigens einen Errorhandler einbauen, den Du in dubioseren Situationen noch mit der undokumentierten Erl()-Funktion austattest.
Bei deren Verwendung mußt Du noch Deine Codezeilen numerieren und diese Indizes auf die neuralgischen Punkte ausweiten:

'...
'Application.Volatile
'Dimensions
Dim ii As String, bold As String, ital As String, rs As String, cs As String, se As String
Dim WikiText As String, fText As String, fName As String
Dim rng As Range
'Dim fZahl As Single
On Error GoTo ErrorHandler
'...
'EmptyRacks
10 fText = ""
20 For Each rng In EmptyRacks
30    If rng.Text <> "" Then
40        fText = fText & rng.Text & " (+" & FullAmmo - rng.Text & ")" & ii
50    Else '0
60        fText = fText & ii
70    End If
80 Next
90 WikiText = WikiText & fText
'...
fCreateWiki = WikiText
ErrorHandler:
If Err.Number <> 0 Then Debug.Print "Error: " & _
  Err.Number & " " & Err.Description & vbCr & _
  "ErrLineNumber: " & Erl()
End Function

Gruß, Mullit

Bild

Betrifft: AW: Funktion gibt sporadisch #WERT! zurück
von: Manne
Geschrieben am: 08.06.2015 19:09:08
Hallo Mullit,
danke für deine Antworten.
Option Explicit habe ich (meistens) an. Bei dem deklarieren der Variablen bin ich mir _ eigentlich sicher, daß dies so richtig ist. Zumindest laut https://msdn.microsoft.com/de-de/library/7ee5a7s1.aspx .


Dim a, b, c As Single, x, y As Double, i As Integer
' a, b, and c are all Single; x and y are both Double

Oder unterscheidet sich VB und VBA hier? Ich habe sie trotzdem mal alle einzeln deklariert, leider ohne sichtbare Änderung.
Geholfen hat aber dein Schuss ins Blaue! .value statt .text und es funktioniert tadellos.
Habe es dann sogar nochmals mit dem ErrorHandler verifiziert. Dies ist im übrigen eine sehr interessante Möglichkeit zur Fehlersuche, welche ich bislang auch noch nicht kannte.
Im Prinzip komme ich mir jetzt gerade etwas blöd vor, da ich vor ein paar Monaten schonmal einen Fall hatte, bei dem sich mit Copy&Paste ein .text eingeschlichen hatte. Allerdings war es da ein Problem von geht gar nicht. Aber das solch ein Fehler sporadisch funktionert/nicht funktioniert ist mir jetzt etwas ganz neues!?
Ich danke dir vielmals für deine Hilfe!
Gruß,
Manne

Bild

Betrifft: AW: Funktion gibt sporadisch #WERT! zurück
von: Mullit
Geschrieben am: 08.06.2015 20:22:20
Hallo Manne,
prima, daß es läuft, ja genau das ist der Punkt, VB.NET und VBA unterscheiden sich da, s.a.
http://msdn.microsoft.com/en-us/library/office/gg264241.aspx

If you do not specify a data type, the Variant data type is assigned by default.

Kann man selbst auch gut nachprüfen:
Option Explicit
Public Sub test()
  Dim strTest1, strTest2, strTest3 As String
  'Das Schlüsselwort Empty wird als Variant-Untertyp verwendet und zeigt einen nicht  _
initialisierten Variablenwert an.
  MsgBox "strTest1: " & TypeName(strTest1) & vbCr & _
    "strTest2: " & TypeName(strTest2) & vbCr & _
    "strTest3: " & TypeName(strTest3)
End Sub

Gruß, Mullit

Bild

Betrifft: AW: Funktion gibt sporadisch #WERT! zurück
von: Manne
Geschrieben am: 08.06.2015 20:56:53
Nochmals Danke!
Man scheint niemals aus zu lernen. :)
Gruß,
Manne

 Bild

Beiträge aus den Excel-Beispielen zum Thema "Funktion gibt sporadisch #WERT! zurück"