Moi,
minulla on taulukossa allekkain useita avattavia luetteloruutuja joissa on vaihtohtoina kyllä ja ei. Jos valitaan kyllä, ei tehdä mitään. Jos taas valitaan ei, pitäisi käynnistyä makro joka kysyy tarkennuksen, eli valitaan 1 tai 2 ja valittu arvo kirjoitetaan luetteloruudun viereen
Itse makrossa ei ole mitään ongelmaa, mutta voinko mitenkään selvittää rivinumeron jolla ko. luetteloruutu on?
Nyt rakenne on sellainen, että jokainen luettoloruutu käynnistää oman makronsa, koodinpätkä näyttää seuraavanlaiselta (x30 on solulinkki kaikista luetteloruuduista):
Public rivi
Sub prioriteetti()
If Range("x30").Value = 2 Then
luku = InputBox("Anna prioriteetti")
Cells(rivi, 13).Value = luku
End If
End Sub
Sub Avattluetteloruutu33_Muuttuessa()
rivi = 30
Run "prioriteetti"
End Sub
Sub Avattluetteloruutu34_Muuttuessa()
rivi = 31
Run "prioriteetti"
End Sub
Saanko tarvittavan rivin selville muuten kuin yllä esittämälläni tavalla, tavoite olisi hoitaa homma mahdollisimman vähillä koodiriveillä toisin kuin nyt.
-Pasi-
minulla on taulukossa allekkain useita avattavia luetteloruutuja joissa on vaihtohtoina kyllä ja ei. Jos valitaan kyllä, ei tehdä mitään. Jos taas valitaan ei, pitäisi käynnistyä makro joka kysyy tarkennuksen, eli valitaan 1 tai 2 ja valittu arvo kirjoitetaan luetteloruudun viereen
Itse makrossa ei ole mitään ongelmaa, mutta voinko mitenkään selvittää rivinumeron jolla ko. luetteloruutu on?
Nyt rakenne on sellainen, että jokainen luettoloruutu käynnistää oman makronsa, koodinpätkä näyttää seuraavanlaiselta (x30 on solulinkki kaikista luetteloruuduista):
Public rivi
Sub prioriteetti()
If Range("x30").Value = 2 Then
luku = InputBox("Anna prioriteetti")
Cells(rivi, 13).Value = luku
End If
End Sub
Sub Avattluetteloruutu33_Muuttuessa()
rivi = 30
Run "prioriteetti"
End Sub
Sub Avattluetteloruutu34_Muuttuessa()
rivi = 31
Run "prioriteetti"
End Sub
Saanko tarvittavan rivin selville muuten kuin yllä esittämälläni tavalla, tavoite olisi hoitaa homma mahdollisimman vähillä koodiriveillä toisin kuin nyt.
-Pasi-
Vastaukset 5
Vanhimmat
on varmaankin ainoa mahdollisuus, sillä luetteloruudut sinänsä eivät ole muuten yhteydessä soluihin. Eli rivin 30 luetteloruudun linkki olisi X30, rivin 31 olisi X31 jne...
Ohessa makro joka toimii kyseisellä periaattella. Ideana on että X-sarakkeen solulinkit ovat alussa tyhjiä, X1-solussa on yhteenlaskukaava joka tutkii että mikä valinta on suoritettu ja etsii kyseisen valinnan sisältävän rivin:
-------------------------------------
Sub Avattluetteloruutu_Muuttuessa()
'
' Macro recorded 29.5.2004 by Excelit.fi
'
'
Range("X1").Select
ActiveCell.FormulaR1C1 = "=SUM(R[1]C:R[99]C)"
Dim ValittuArvo As String
ValittuArvo = Range("X1")
Range("X2").Select
Cells.Find(What:=ValittuArvo, After:=ActiveCell, LookIn:=xlValues, LookAt:= _
xlPart, SearchOrder:=xlByColumns, SearchDirection:=xlNext, MatchCase:=False) _
.Activate
Dim Rivi As String
Rivi = ActiveCell.Row
If Range("x" & Rivi & "").Value = 2 Then
luku = InputBox("Anna prioriteetti")
Cells(Rivi, 13).Value = luku
End If
'Poistetaan valitut arvot
Range("X2:X100").Select
Selection.ClearContents
Range("X" & Rivi & "").Select
End Sub
systeemi, hieno!
Kysymykseen lipsahti pieni virhe, tietenkään kaikille luetteloruuduille ei voi olla sama solulinkki koska tällöin kaikkien luetteloruutujen sisältö olisi aina sama. Muuten kirjoittamasi ohjelma toimii hienosti, mutta luetteloruutujen valintojen tulisi jäädä näkyviin valinnan jälkeen. Minun mokani, anteeksi.
Voisin soveltaa samaa ideaa etsimällä viimeisen täytetyn solun, mutta koska taulukkoa ei välttämättä täytetä ylhäältä alas rivi kerrallaan, ei se toimisi. Koitan kehitellä jotain.
Kiitos ideasta!
-Pasi-
Yritän näin: lisään temppuun vielä yhden sarakkeen. Tämä sarake on alussa tyhjä ja sarakkeen jokaisessa solussa on =OmaFunktio(Xrivi), eli funktio joka käynnistyy kun viereisen X-solun arvo muuttuu. Tämä funktio etsii kyseisestä sarakkeesta suurimman arvon, joka siis alussa on 0, ja lisää siihen aina yhden ja kirjoittaa tämän numeron soluun jossa funktio on. Näin saan järjestysnumeron joka kertoo mikä solu on muuttunut viimeksi, ja voin etsiä tämän perusteella oikean rivin!
Funktioon lisään vielä ehdon joka poistaa järjestysnumeron solusta jos luetteloruudun solulinkki muuttuu nollaksi, eli valintoja voi myös poistaa järjestelmän menemättä sekaisin.
Hmmm... onnistuukohan tuo, täytyy kokeilla tai sitten tyytyä alkuperäiseen ratkaisuun..
-Pasi-
Laita soluihin ,joihin halusit valintaruudun, kyllä/ei kelpoisuusehto ja määrittele solut koodissa
Private Sub Worksheet_Change(ByVal Target As Range)
Dim X As Integer
Dim alue As Range
' määritä alue
Set alue = Range("D1:D10, D12, D15")
Application.EnableEvents = False
'jos useampi solu valittu
If Target.Cells.Count > 1 Then
Application.EnableEvents = True
Exit Sub
End If
If Not Intersect(Target, alue) Is Nothing Then
If Target.Text = "kyllä" Then
uudestaan:
X = Application.InputBox("anna luku 1 tai 2", Type:=1)
If X = 1 Or X = 2 Then
Target.Offset(0, 1) = X
Else
MsgBox "Sinun on annettava luku 1 tai 2"
GoTo uudestaan
End If
Else
Target.Offset(0, 1) = ""
End If
End If
Application.EnableEvents = True
End Sub
homman ihan toisella tavalla, eli luovuin alasvetovalikosta kokonaan ja tein makron joka käynnistyy kun solua klikkaa. Solun ollessa tyhjä siihen tulee "Kyllä" ja jos solussa on jo valmiiksi "Kyllä", vaihtuu tekstiksi "Ei" ja käynnistyy toinen makro joka kysyy tarkentavaa numeroa. Kolmannen kerran klikattaessa käyttäjältä varmistetaan solujen tuhjennys ja solut tyhjennetään jos tämä ok.
Kiitos kuitenkin vastauksestasi, siitä luultavasti on apua joskus tulevaisuudessa.
PS. Aivan aluksi kokeilin kelpoisuustarkastusta, ja sillä sainkin homman toimimaan, se aiheutti pientä päänvaivaa että kelpoisuustarkastusta käytämällä solun sisältö muuttui aina kaksi kertaa, eli numeroa kysyvä makro käynnistyi aina kahdesti. Tästä eroon päästäkseni tein pari Public-muuttujaa joihin tallensin tiedon siitä minkä solun sisältö oli edellisen kerran muuttunut ja miksi tekstiksi se muuttui. Näiden perusteella sain sopivaan kohtaan lauseella If jotakin then exit sub estettyä makron suorituksen uudestaan...
-Pasi-