Just nu i M3-nätverket
Gå till innehåll

Fel värden i textbox via val i combobox i formulär


RichardN

Rekommendera Poster

Hej!

 

Förutsättningarna är som följer. Excel 2010. Koden nedan hör till ett formulär (UserForm2) som ska uppdatera rader i ett excelark (Sheet1). Formuläret populeras med hjälp av en combobox (ComboBox1). Detta fungerar med ett undantag, vad jag har sett hittills: När jag väljer rad 1 i comboboxen så får jag upp värdena för rad 10. Om jag sedan får för mig att köra själva uppdateringen så sparas datan in på rad 1.

Jag har sökt med ljus och lykta efter en lösning på de flesta forum på nätet. Det som är kvar nu är krypa till korset och söka hjälp.

 

Jag måste också tillägga att jag inte är så värst självgående i VBA. Största delen av koden nedan har kommit till genom klipp och klistra. Så om det är någon som har tid att förbarma sig över mitt problem så skulle jag uppskatta förklaringar. Men, jag klarar hyffsat av att läsa en del kod, så om det tar för lång tid med förklaring så tar jag vad jag kan få!

 

Tack så mycket på förhand!

/Richard

 

Private Sub CButtonExplainSkydd_Click()
UserFormSkyddszon.Show
End Sub

Private Sub cmdDate_Click()

 DatePickerForm2.Show
End Sub

Private Sub ComboBox1_Change()
On Error GoTo 1
txtKartDat.Value = MyRange.Find(ComboBox1).Offset(0, 4)
txtInventerare.Value = MyRange.Find(ComboBox1).Offset(0, 8)
txtEUID.Value = MyRange.Find(ComboBox1).Offset(0, 55)
txtUID.Value = MyRange.Find(ComboBox1).Offset(0, 45)
cboxInvTyp.Value = MyRange.Find(ComboBox1).Offset(0, 47)

txtVattDrag.Value = MyRange.Find(ComboBox1).Offset(0, 48)
txtFlygbild.Value = MyRange.Find(ComboBox1).Offset(0, 10)
txtTerrKart.Value = MyRange.Find(ComboBox1).Offset(0, 15)
txtFsghKart.Value = MyRange.Find(ComboBox1).Offset(0, 16)
txtStartX.Value = MyRange.Find(ComboBox1).Offset(0, 58)
txtStartY.Value = MyRange.Find(ComboBox1).Offset(0, 59)
txtSlutX.Value = MyRange.Find(ComboBox1).Offset(0, 60)
txtSlutY.Value = MyRange.Find(ComboBox1).Offset(0, 61)

txtStrNr.Value = MyRange.Find(ComboBox1).Offset(0, 3)
txtStrLen.Value = MyRange.Find(ComboBox1).Offset(0, 19)
cboxSida.Value = MyRange.Find(ComboBox1).Offset(0, 18)
cboxInvAndel.Value = MyRange.Find(ComboBox1).Offset(0, 22)

cboxTotalTackB4.Value = MyRange.Find(ComboBox1).Offset(0, 23)
txtBoxB4_5_50.Value = MyRange.Find(ComboBox1).Offset(0, 24)
txtBoxB4_5.Value = MyRange.Find(ComboBox1).Offset(0, 25)
cboxMossodlB4.Value = MyRange.Find(ComboBox1).Offset(0, 27)

cboxTotalTackB5.Value = MyRange.Find(ComboBox1).Offset(0, 28)
txtBoxB5_5_50.Value = MyRange.Find(ComboBox1).Offset(0, 29)
txtBoxB5_5.Value = MyRange.Find(ComboBox1).Offset(0, 30)

cboxMossodlB5.Value = MyRange.Find(ComboBox1).Offset(0, 32)
txtDomTrad.Value = MyRange.Find(ComboBox1).Offset(0, 33)

cboxBreddArtMark.Value = MyRange.Find(ComboBox1).Offset(0, 34)
cboxDomMarkTyp.Value = MyRange.Find(ComboBox1).Offset(0, 35)
cboxBreddSkogsMark.Value = MyRange.Find(ComboBox1).Offset(0, 36)
cboxDomMarkSkog.Value = MyRange.Find(ComboBox1).Offset(0, 37)

cboxMedelBredd.Value = MyRange.Find(ComboBox1).Offset(0, 38)

cboxBuskskikt.Value = MyRange.Find(ComboBox1).Offset(0, 39)

cboxSkuggning.Value = MyRange.Find(ComboBox1).Offset(0, 41)

cboxOversvam.Value = MyRange.Find(ComboBox1).Offset(0, 52)
txtRavinBrant.Value = MyRange.Find(ComboBox1).Offset(0, 50)

txtOvrigt.Value = MyRange.Find(ComboBox1).Offset(0, 42)

Labe21 = ComboBox1
1 End Sub

Private Sub CommandButton1_Click()
Range("A3").Select
With ActiveCell.Offset(ComboBox1.ListIndex, 0)


.Offset(0, 0) = ComboBox1
.Offset(0, 4) = txtKartDat
.Offset(0, 8) = txtInventerare
.Offset(0, 55) = txtEUID
.Offset(0, 45) = txtUID
.Offset(0, 47) = cboxInvTyp

.Offset(0, 48) = txtVattDrag
.Offset(0, 10) = txtFlygbild
.Offset(0, 15) = txtTerrKart
.Offset(0, 16) = txtFsghKart
.Offset(0, 58) = txtStartX
.Offset(0, 59) = txtStartY
.Offset(0, 60) = txtSlutX
.Offset(0, 61) = txtSlutY

.Offset(0, 3) = txtStrNr
.Offset(0, 19) = txtStrLen
.Offset(0, 18) = cboxSida
.Offset(0, 22) = cboxInvAndel

.Offset(0, 23) = cboxTotalTackB4
.Offset(0, 24) = txtBoxB4_5_50
.Offset(0, 25) = txtBoxB4_5

.Offset(0, 27) = cboxMossodlB4

.Offset(0, 28) = cboxTotalTackB5
.Offset(0, 29) = txtBoxB5_5_50
.Offset(0, 30) = txtBoxB5_5

.Offset(0, 32) = cboxMossodlB5
.Offset(0, 33) = txtDomTrad

.Offset(0, 34) = cboxBreddArtMark
.Offset(0, 35) = cboxDomMarkTyp
.Offset(0, 36) = cboxBreddSkogsMark
.Offset(0, 37) = cboxDomMarkSkog

.Offset(0, 38) = cboxMedelBredd

.Offset(0, 39) = cboxBuskskikt

.Offset(0, 41) = cboxSkuggning

.Offset(0, 52) = cboxOversvam
.Offset(0, 50) = txtRavinBrant

.Offset(0, 42) = txtOvrigt




       Application.DisplayAlerts = False
   ActiveWorkbook.SaveAs ThisWorkbook.Path & "\" & "Protokoll_B.xlsm"
   Application.DisplayAlerts = True
   MsgBox "Uppdaterat och sparat"
End With
Unload Me
End Sub

Private Sub CommandButton3_Click()
End
End Sub



Private Sub UserForm_Initialize()
For Each cell In MyRange
ComboBox1.AddItem cell
Next
End Sub

Function MyRange()

Set MyRange = Sheet1.[a3:a5000]
End Function



Länk till kommentar
Dela på andra webbplatser

Svårt att se exakt vad du gör i koden. Eller rättare sagt, svårt att se exakt vilket resultat du får.

 

Några tankar

Du fyller din combobox med ett antal värden. Du använder sedan valt värde för att söka inom en begränsad mängd celler efter den rad/de värden du ska fylla dina celler med.

Och för varje textruta som ska få värden söker du på nytt efter rätt rad.

Varför inte söka en gång och använda samma referens, i stil med

Set myRn = MyRange.Find(ComboBox1)

 

och exempelvis

txtVattDrag.Value = myRn.Offset(0, 48)

eller än hellre

With myRn

txtVattDrag.Value = .Offset(0, 48)

 

då kan du enkelt kontroller att referensen blir det du önskar.

Men varför söker du? Du vet ju vika objekt du fyllt comboboxen med, kan du inte använda

ComboBox1.ListIndex

för att ta fram index för träff och därvid skapa din referens. Enklare, snabbare, säkrare.

 

en annan sak

Range("A3").Select
With ActiveCell.Offset(ComboBox1.ListIndex, 0)

Nej. Bort med Activecell!

Skriv som

With Sheet1.Range("A3").Offset(ComboBox1.ListIndex)

Länk till kommentar
Dela på andra webbplatser

Hej Monshi!

 

Tack för att du tar dig tid!!!

 

Jag har implementerat dina förslag, men tyvärr är resultatet detsamma som tidigare (värden från rad 10 kommer upp i stället för värden från rad 1).

 

Jag har gjort ytterligare felsökning (eller, ja, det var mer tur än skicklighet...) och kommit fram till att om jag minskar ner MyRange till att bara omfatta A3:A11 (9 rader alltså) så läses rad 1 in rätt! Ger det några ledtrådar om vad som är vajsing?

 

Hälsningar!

/Richard

Länk till kommentar
Dela på andra webbplatser

Ove Söderlund

Jag framkastar en liten vild gissning om att kanske kolla på om du behöver sätta Option Base=1 överst i modulen.

Länk till kommentar
Dela på andra webbplatser

Hej Ove!

 

Tack för förslaget!

Har lagt till Option Base 1, tyvärr utan framgång.

Läste sedan på lite om option base och kom fram till att det har med arrays att göra. Och då förklarar det varför det inte påverkar resultatet här.

Länk till kommentar
Dela på andra webbplatser

Vilket är sökordet som blir fel?

Om du tar samma sökord och testar det i sökrutan på bladet, vilken rad hamnar du på då?

 

Om du tittar på den cell (myRn) som sökfunktionen hittar, stämmer det värdet med det du sökt efter?

(du kan undersöka det via brytpunkt i koden eller använda Debug.Print för att skriva ut det i direktfönstret under körning)

Länk till kommentar
Dela på andra webbplatser

Ove Söderlund

En annan fundering jag har är:

Har du anropat funktionen MyRange() innan du initierar formuläret?

Mitt förslag vore då att testa följande kodändringar:

 

Private Sub UserForm_Initialize()

Init_MyRange

For Each cell In MyRange
ComboBox1.AddItem cell
Next
End Sub

Sub Init_MyRange()

Set MyRange = Sheet1.[a3:a5000]

End Sub

Länk till kommentar
Dela på andra webbplatser

Det är txtStrNr som är fel.

excel.gif

Kolumn A (där det söks värden, A3:A5000) innehåller endast siffror. Dessa räknas upp med automatik när en ny post läggs till i inmatningsformuläret (UserForm1).

Kolumnen som blir fel är D3 (där txtStrNr finns). Den borde ju alltså innehålla värdet 1 och inte 10 när jag väljer 1 i Combobox1.

 

A3, som är den första som hittas via bladets sökfunktion innehåller då alltså värdet 1. Då har jag haft A3 markerad när jag använder sökfunktionen. Detta eftersom det är där .find börjar leta(?).

 

Jag lyckas tyvärr inte lista ut hur man använder Debug.Print och brytpunkt för att få ut något vettigt. :angry:

 

/Richard

 

Edit: Var det nåt sånt här du menade med Debug.Print?

txtStrNr.Value = myRn.Offset(0, 3)
Debug.Print txtStrNr.Value

Resultatet blir i allafall 10.

Länk till kommentar
Dela på andra webbplatser

En annan fundering jag har är:

Har du anropat funktionen MyRange() innan du initierar formuläret?

Mitt förslag vore då att testa följande kodändringar:

 

Private Sub UserForm_Initialize()

Init_MyRange

For Each cell In MyRange
ComboBox1.AddItem cell
Next
End Sub

Sub Init_MyRange()

Set MyRange = Sheet1.[a3:a5000]

End Sub

 

Har nu provat det också. Det ger följande felmeddelande: "Körfel nr '13'.: Inkompatibla typer" och stannar på "For Each cell In MyRange".

 

/Richard

Länk till kommentar
Dela på andra webbplatser

Ove Söderlund

Ok, nytt förslag där jag utgått ifrån din skärmdump. En liten omkonstruktion av Sub ComboBox1_Change().

 

Private Sub ComboBox1_Change()

On Error GoTo 1

' Bör räcka att endast hitta den rad som väljs, och från den raden hämta respektive kolumnvärde

' Listindex har värde mellan 0 (första värdet i ComboBox och antal poster i (ComboBox - 1)
ActualRowInSheet = ComboBox1.ListIndex + 1

' Tabellen i kalkylarket börjar på rad 3 (2=tabellrubrik) därav 2 + ActualRowInSheet
txtKartDat.Value = Worksheets("Sheet1").Cells(2 + ActualRowInSheet, 4)
txtInventerare.Value = Worksheets("Sheet1").Cells(2 + ActualRowInSheet, 8)
txtEUID.Value = Worksheets("Sheet1").Cells(2 + ActualRowInSheet, 55)
txtUID.Value = Worksheets("Sheet1").Cells(2 + ActualRowInSheet, 45)
cboxInvTyp.Value = Worksheets("Sheet1").Cells(2 + ActualRowInSheet, 47)
' osv.... med alla variabeltilldelningar

Länk till kommentar
Dela på andra webbplatser

Tack igen Ove!

 

Detta fungerar!!! Men, ett litet bekymmer uppstår. Jag vet inte om det går att lösa enkelt med kod, men jag hoppas!!! Det är nämligen som så att det blir fel ordning i kolumnerna nu. I originalet så var kolumn A= 0, i denna kod så är kolumn A=1. Det får till följd att när formuläret sparas och uppdateras så är det en förskjutning i kolumnerna. Eftersom kolumnerna räknas annorlunda där. Nu hade det väl inte varit hela världen att ändra överallt, om det hade rört sig om bara detta formuläret. Men det är en hel drös till...

Så, går det att på något enkelt sätt att kodmässigt rätta till detta? Gissar att det kan handla om "Offset"...

 

Ett exempel:

txtKartDat.Value = Worksheets("Sheet1").Cells(2 + ActualRowInSheet, 4)

Läser in värdet från kolumn D när det skulle ha tagit värdet från kolumn E. Alltså, enligt skärmdump på formuläretovan, Karteringsdatum (txtKartDat) fylls med Sträcka Nr (txtStrNr).

 

Inser att förklaringen är lite rörig. Men hoppas att det ändå går att förstå.

 

/Richard

Länk till kommentar
Dela på andra webbplatser

Ove Söderlund

Ok, svaret är mkt riktigt att det är Offset som ställer till det. Du får nog addera +1 till "Offset"-värdena i subben, eftersom Offset fungerar som att det tar X antal positioner _efter_ startvärdet/range, och i min kod är det absoluta positioner, alltså, 4 för kolumn 4 "D".

Detta med relativa och absoluta referenser kan ställa till ibland :)

Länk till kommentar
Dela på andra webbplatser

Sådär, då var det klart med alla formulären. Oves förslag fungerade utmärkt.

 

Stort tack till Monshi och Ove Söderlund för att ni står ut med oss okunniga!

 

Hälsningar!

/Richard

Länk till kommentar
Dela på andra webbplatser

Arkiverat

Det här ämnet är nu arkiverat och är stängt för ytterligare svar.

×
×
  • Skapa nytt...