Moro!
Olen yrittänyt tässä tehdä sellaista taulukkolaskuria komponenteille. Laskurissa pitää ensin valita Tyyppi jonka jälkeen jokin tyypin mukainen valmistaja ja sitten jokin malli valmistajalta. Kun valmistaja on valittu taulukossa näkyisi tietoja kyseisestä mallista esim jännite,virta,teho... näitä tietoja käytettäisiin sitten toisessa välilehdessä laskukaavoissa.
ELI sitten itse ongelmaan olen lähteny toteuttamaan tätä erittäin "purkka"-tyylillä eli olen tehny ison taulukon johon olen tehny pikasuodatuksen. Tälla tavallahan pystyn toteuttamaan tuon valinta prosessin (tyyppi,valmistaja,malli).
Sitten sen mallien tietojen kopioinnin toiseen välilehteen olen toteuttanut välisummalla, mutta minun olisi tarkoitus saada kopioitua myös tuon sen tyypin,valmistajan ja mallin nimet kyseiseen välilehteen.
Eli onko jotenki mahdollista kopioida suodatetusta taulukosta vain näkyviä soluja?
-tämä oli varmaan todella epäselvästi selitetty, mutta toivottavasti joku ymmärtää
Moi saecci!
VBA:lla onnistuu monikin asia, elikä tutki ja mieti oheistä koodia...
'Taul1 Private Sub CommandButton1_Click() Dim alue As Range Dim solu, rivi, sarake Set alue = Sheets(1).UsedRange For Each solu In alue rivi = solu.Row sarake = solu.Column If Rows(rivi).Hidden = False Then Sheets(2).Cells(rivi, sarake).Value = solu.Value End If Next End Sub
hmm... okei. Kiitos Nea! Ilmeisesti tuossa tehdään userformiin commandbutton, mutta pitää kyllä vähän tutkailla miten tuo toimii ja kuinka saan hyödynnettyä sitä. Ei ole tuota vba:ta aikaisemmin tullut pahemmin käytettyä :)
En nyt oikein ihan ymmärrä tuota koodia tai ainakaan en saa sitä toimimaan haluamallani tavalla. Nuo Dim alue... ovat kai pelkkiä muutujien määrittelyitä?
Mutta mikä kohta tuossa on se jossa määritellää se sarake jonka näkyviä ja piilotettuja soluja tarkastellaan? Kun eikö tuossa "Sheets(2).Cells(rivi, sarake).Value = solu.Value" määritetä se solu siellä toisessa välilehdessä johon halutaan kopioida.
Kun yritin suorittaa tätä koodia sillä tavalla miten sen itse ymmärsin ni se "kopioi" kyllä oikeaan soluun, mutta se vain pyöritti kaikki taulukon yhden rivin tiedot läpi nopeasti (tyyppi,valmistaja,malli,jännite,virta,teho..) jonka jälkeen solu oli taas tyhjä.
Haluasin, että se kopiosi suodatuksesta tyypin tiettyyn soluu, valmistajan omaansa ja niin edespäin.
Moi taas saecci!
No selvennetään hieman elikä Range objektin avulla voidaan valita työkirjan talusta haluttu alue. Esimerkissä Range objektimuuttuja alue on alustettu ensin Dim lauseella ja sen jälkeen muuttujan arvo eli tässä tapauksesa taulun Sheets(1).UsedRange tarkoittaa aluetta joka muodostuu taulun viimeisen käytössä olevan rivin ja viimeisen käytössä olevan sarakkeen muodostamasta solualueesta. Sanotaan että taulussa on rivillä 129 missä tahansa sarakkeessa jokin tieto ja vaikkapa sarakkeessa J (sarake 10) millä tahansa rivillä jokin tieto niin taulun UsedRange on tällöin Range("A1:J129").
VBA-koodissa haluttu alue asetetaan Range-objektimuuttujan arvoksi Set lauseella.
Esim. Jos halutaan asettaa Range-objektimuuttujan arvoksi alue joka muodostuu yhden ainoan sarakkeen esim sarakkeen J ja taulun kaikkien kaytössä olevien rivien määrän muodostamasta solualueesta niin...
'alustetaan objektimuuttuja Dim alue As Range 'alustetaan 3 Variant tyyppistä muuttujaa Dim rivi, solu, rivit 'aseteaan muuttujan rivit arvoksi taulun Taul1 'viimeisen käytössä olevan rivin rivinumero rivit = Taul1.Cells.SpecialCells(xlCellTypeLastCell).Row 'asetetaan objektimuuttujan alue arvoksi sarakkeen J 'ja muuttujan rivit arvon mukaan määräytyvä solualue Set alue = Taul1.Range("J1:J" & CStr(rivit)) 'asetetaan muuttujan rivi arvoksi 0 rivi = 0 'käydään for each silmukassa läpi muutujan alue 'kaikki solut ensimmäisestä viimeisen... For Each solu In alue 'asetetaan muuttujan rivi arvoksi 'kulloisenkin solun rivinumero rivi = solu.Row 'tutkitaan If ehtolauseella onko 'kulloisenkin solun rivi näkyvä vai ei 'ja jos rivi ei ole piilossa niin... If Taul1.Rows(solu.Row).Hidden = False 'kasvatetaan muuttujan rivi arvoa 1:llä rivi = rivi + 1 'kopioidaan taulun Taul2 sarakkeen A 'rivin rivi solun arvoksi muttujan solu arvo Taul2.Range("A" & CStr(rivi)).Value = Solu.Value End If Next
Toivottavasti oheisen esimerkin avulla alkaa hieman valjeta. Kannattaa myös alkaa tutkimaan mitä kaikkea VBA-editorin ohjeista ja esimerkeistä löytyy (Suositus: mikäli ohjeita ei ole asennettu niin asenna)...
Kiitos taas! :)
Nyt minun on viellä vaan muokkailla tuota niin, että suodatus kopioituu vaikka soluun C11 eikä koko sarakkeelle C. Kun tuossahan se kopionti paikan rivinumero riippuu suodatuksen rivinumerosta. Yritin yhdistellä tätä koodia vähä tuohon ylempään millä pystyi määrittämään tarkalleen sen solun, mutta en viellä ihan saanut toimimaan. Mutta eiköhän tämä vielä tästä.
nii itte oon yhtä ainoota solua käsitelly komennolla cells(vaakarivi,pystyrivi)
esim; sheets("taulukko1").cells(2,2)=sheets("taulukko2
koipio tietoa taulukon 2 ruudusta 2E taulukon1 ruutuun 2B.
tällä alla olevalla koodin pätkällä oon kopioinu tiettoo toisaalle
dim a as single
a=0 'tällä määritetään miltä riviltä aloitetaan
do until sheet("taul1").cells(a,1)<>"" 'jos kohde solu on tyhjä ei tee mitään
a=a+1
sheets("taul2").cells(a,1)=sheets("taul1").cells(a,1) 'muulloin kopio kohdesolun toisaalle
loop
Jooh, tuo toimisi muuten, muttä tässä kun on pikasuodatus niin rivi mistä kopioidaan voi vaihdella 2E:stä vaikka 1000E:hen riippuen kuinka paljon suodatettavassa taulussa on tavaraa ja minkä rivin tiedot suodattuu.
jos vaikka taulu olisi muotoa:
[tyyppi] [valmistaja] [malli] [speksi1] [speksi2] [speksi3] m,puhelin nokia n8 x x x m.puhelin nokia e7 x x x m.puhelin htc desire x x x
ja jokin suodatuksen jälkeen näyttää tältä
[tyyppi] [valmistaja] [malli] [speksi1] [speksi2] [speksi3] m.puhelin htc desire x x x
jolloin 2 ensimmäistä riviä häviävät ja "otsikon" jälkeinen rivi onkin 4.
En tiedä sitten pitäisikö tässä tehdä vba:lla jokin sellainen, että kopioi vain silloin kun näkyviä soluja on yksi. Visible = 1 tai jotain...
no nii toellaan.. unohtu tuo suodatus juttu.... ja sitte vielä pari riviä vois tuossa koodissa vaihtaa paikkaa...
ääh.. ei tää nyt oikee lähe :/
Sain myös tämmöisen mallikoodin, mutta en sitä ole viellä saanut toimimaan
Private Sub CommandButton1_Click() Dim Rng As Range If Taul2.FilterMode Then With Taul2.AutoFilter.Range Set Rng = .Offset(1, 1).Resize(.Rows.Count - 1, 1).SpecialCells(xlCellTypeVisible) End With Rng.Copy Taul1.Range("C11") MsgBox "Kopioitu", vbOKOnly Or vbInformation, "Information" Else MsgBox "Ei ole suodatettu", vbOKOnly Or vbInformation, "Information" End If End Sub
tai kyllä tuo antaa nuo "Kopioitu" ja "Ei ole suodatettua" vastaukset, mutta en ole viellä saanut tuon kopioimaan oikeasti jotain.
Edit: no nyt sain tulostamaan ensimmäisen suodatuksen arvon eli tuon "tyypin" kun muutin "Set Rng = .Offset(1, 0)...", mutta en ole viellä keksinyt miten saan kopioitua muut kohdat.
Aihe on jo aika vanha, joten et voi enää vastata siihen.