09. august 2007 - 19:34Der er
24 kommentarer og 1 løsning
VBA Excel kode virker hver 2 gang
Jeg er stødt på et noget underligt fænomen.
Min kode (vist herunder) virker kun hver 2 gang. Den fejler i linien med den første
ActiveCell.Offset(1, 0).Select
Hver anden gange jeg løber koden igennem forløber det fint. Anden gang, modtager jeg fejlen:
"Run-time error '1004': Application-defined or object-defined error"
Jeg har puklet med det i flere timer og kan ganske enkelt ikke gennemskue det.
Kan nogen af jer?
Har i behov for at se mere kode, så sig til :)
___ KODE START ___
Public Function FindB2Value() Dim counter As Byte ReDim postvalue(postcounter) counter = 0
Application.ScreenUpdating = False
Application.Goto reference:="Konto"
Do Until counter = postcounter
(FEJLER HER) ActiveCell.Offset(1, 0).Select
If ActiveCell.Value = "2" Then counter = counter + 1 ActiveCell.Offset(0, 14).Select postvalue(counter) = ActiveCell.Value ActiveCell.Offset(0, -14).Select End If Loop
Jeg skal ikke gøre mig klog på Excel programmering, arbejder mest med Access, men jeg undrer mig over, at du har defeneret det som en funktion, når den øjensynligt ikke returnerer en værdi. Var det ikke bedre at ændre det til en subrutine i så fald?
Hvis counter aldrig når værdien af postcounter, rammer du bunden af arket. Det vil give den omtalte fejl. Og hvad er værdien postcounter? Det er ikke defineret i din function!
Tak for svar, akyhne. Du har ret i det du pointere, men hvad skulle forhindre koden i at lykkedes hver anden gang.
Hvis jeg i øvrigt ændrer IF betingelsen fra Activecell.Value til Activecell.Text (hvilket i mit tilfælde ville forbedre funktionens stabilitet), får jeg fejlen hver gang - altså koden lykkedes slet ikke. Hva de to elementer har med hinanden at gøre - det må guderne vide.
postcounter er en global variabel. Ligeledes er der meget mere kode end det viste. Tænkte at jeg i første omgang kun ville poste den kode samt det tilhørende der fejlede.
Postcounter stammer fra en anden sub, der tjekker hvor mange poster der skal behandles.
ReDim postvalue(0) Application.Goto reference:="Konto" S = ActiveCell.Row T = ActiveCell.Column Slut = ActiveCell.Offset(65536 - S).End(xlUp).Row
MitArray = Range(Cells(S + 1, T), Cells(Slut + 14, T)) For I = 1 To UBound(MitArray) If MitArray(I, 1) = "2" Then counter = counter + 1 ReDim postvalue(counter) postvalue(counter) = MitArray(I + 14, 1) End If Next
Det går langt hurtigere.
Læg mærke til placeringen af ReDim postvalue(counter). Hvis du ikke med sikkerhed har redimmet til en værdi der kan indeholde antallet af 2-taller fundet, vil du også få en fejl.
Det var lidt nemmere, hvis du smed hele koden, eller forklarede lidt om hvad det er der skal ske.
ReDim postvalue(0) Application.Goto reference:="Konto" S = ActiveCell.Row T = ActiveCell.Column Slut = ActiveCell.Offset(65536 - S).End(xlUp).Row
MitArray = Range(Cells(S + 1, T), Cells(Slut + 14, T)) For I = 1 To UBound(MitArray) If MitArray(I, 1) = "2" Then counter = counter + 1 ReDim Preserve postvalue(counter) postvalue(counter) = MitArray(I + 14, 1) End If Next
Har absolut ingen anelse om hvad der foregår. Men ved et lille eksperiment ifm. noget andet, delte jeg koden op. Nu virker funktionen som tiltænkt, hver gang.
Application.ScreenUpdating er defineret med True i bunden. Den nederste del af koden er blot ikke skrevet med her, så derfor kan du ikke se det.
Har lidt problemer med at få tilpasset dit forslag til mit behov. Men ideen er følgende:
Jeg har et regneark med et antal kolonneoverskrifter (deriblandt "Navn", "Konto" og "Beløb") og et antal rækker med tilhørende data.
Nogenlunde sådan her:
|Navn| .... |Konto| .... |Beløb| -------------------------------- X-navn ....... 0 ....... 100 kr. Y-navn ....... 2 ....... 200 kr.
Og så fremdeles ..
Meningen er så, at samle alle de poster på konto "2" op i en array variabel, med deres respektive navn og beløb. Disse data skal siden indsættes i et andet ark.
Antallet af rækker kan variere og ligesådan kan antallet af kolonner. Så derfor blir det nødt til at være et array.
Hvis du har et ark med definerede navneområder "Navn" i A1, "Konto" i B1 og "Beløb" i C1 med tilhørende værdier nedenunder, og gerne vil finde bestemte kontoværdier, kan du bruge noget lignende denne:
Sub test() FindKonto = InputBox("Skriv kontonummeret du søger:", "Skriv kontonavn") ReDim postvalue(0) Application.Goto reference:="Konto" S = ActiveCell.Row T = ActiveCell.Column Slut = ActiveCell.Offset(65536 - S).End(xlUp).Row
MitArray = Range(Cells(S + 1, T - 1), Cells(Slut + 14, T + 1)) For I = 1 To UBound(MitArray) If MitArray(I, 2) = "2" Then counter = counter + 1 ReDim Preserve postvalue(counter) postvalue(counter) = MitArray(I, 1) & "|" & MitArray(I, 1 + 1) & "|" & MitArray(I, 1 + 2) End If Next
Sheets("Ark2").Select
For I = 1 To UBound(postvalue) Navn = Split(postvalue(I), "|") Range("A" & I).Value = Navn(0) Range("B" & I).Value = Navn(1) Range("C" & I).Value = Navn(2) Next End Sub
Jeg har sendt arket til dig. Til andre der gerne vil vide hvad jeg har lavet: nicolaus har brugt koden fra 10/08-2007 19:36:58 sammen med en form der lister værdierne. Derfor poster jeg ikke mere kode her for andres skyld. Eneste ændring er at der lige skal dimmes en værdi, øverst i koden: Dim counter as long.
Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.