Voit itse lisätä ja muuttaa sisältöä muokkaa-painikkeiden avulla
Ennen tallennusta suositellaan ottamaan kopio muokkausruudusta (ctrl-a -> ctrl-c)
Olet itse vastuussa tämän teoksen käytöstä aiheutuvista vahingoista Lue lisää.
VBA
Johdanto[muokkaa]
Visual Basic for Applications (VBA)
Katso lisää funktioita sivulta Microsoft 365
Käyttöönotto[muokkaa]
- Tiedosto > Asetukset > Valintanauhan mukauttaminen > valitse Kehitystyökalut > OK
- Kehitystyökalut-valikko ilmestyy näkyville ikkunan yläosaan.
- Visual Basic-painike avaa uuden makrojen muokkausikkunan.
- Insert > Module
- Lisää makron koodi ruutuun
- Aja makro play-painikkeesta tai tee makrolle sitä kutsuva painike välilehdelle.
TAI Jos välilehdistä ei löydy kohtaa 'Kehitystyökalut': Klikkaa ikonitoimintorivillä hiiren oikeaa > Mukauta valintanauhaa... > Valitse Kehitystyökalut
Tallentaminen[muokkaa]
Tiedostopääte on m-loppuinen.
Virheenetsintä[muokkaa]
Paina F1 kun virhekohta on valittuna tai joku muu kohta on valittuna.
Objekti[muokkaa]
Wordissa tiedosto-objekti (document), joka sisältää kappale-objekteja (paragraph). Excelissä esim. väilehti. Objektin määritelmää kutsutaan luokaksi (class), jolla objekti luodaan ja ilmennetään. Objektia voidaan muokata asettamalla sen ominaisuuksia (property) ja kutsumalla sitä metodeilla (method). Metodi saa objektin toimimaan jollain tavoin.
- Application.ActiveDocument.Save - tallentaa aktiivisena olevan tiedoston. Document on objekti. Save on metodi.
- Application.ActiveDocument.SaveAs ("tiedostonimi.docx") - SaveAs-metodi edellyttää parametrin (parameter), joka annetaan metodin jälkeen.
- Application.ActiveSheet.Range("A1").Select ja Application.Selection.Value = "Teksti" - Ominaisuuden asettaminen ja lukeminen tapahtuu samalla tavalla. Application on objekti, ActiveSheet on objekti. Select on metodi. Selectionin value-ominaisuuteen tallennetaan teksti, joka ilmenee A1-solussa.
Excel[muokkaa]
- &: Jos VBA-koodissa netissä on esim. & ja tulee virheilmoitus ajettaessa makroa. Poista amp; ja jätä jäljelle &
Oma objekti (Dim)[muokkaa]
Kutsutaan muuttujaksi (variable). Objektin tyyppi määritellään ensin Dim-statementilla. Sen jälkeen objektille voidaan määritellä arvot ja käyttää muutoin.
Dim OmaMerkkijonoMuuttuja As String OmaMerkkijonoMuuttuja = "tekstiä" Worksheets(1).Range("A1").Value = OmaMerkkijonoMuuttuja
Dim Muuttuja As Worksheet Dim Muuttuja1 As Worksheet, Muuttuja2 As Long Dim Muuttuja As Variant Dim Muuttuja As String Dim Muuttuja As Range Dim Muuttuja As Integer Dim Muuttuja As Long jne.
Muuttuja[muokkaa]
- Huomaa muuttujan käyttötarkoitus ja sen mukaan määrittele object tai string (ks. otsikko Dim) ja käytä set tai let.
- Jos käytössä on useita välilehtiä, kannattaa välilehdet nimetä esim. seuraavasti:
Dim Src As Worksheet <--Src voi olla muukin sana Dim Trg As Worksheet Set Src = ActiveWorkbook.Worksheets("välilehdennimi1") Set Trg = ActiveWorkbook.Worksheets("välilehdennimi2")
- Alueen voi nimetä esim. seuraavasti:
Dim aluenimi As Range Set aluenimi = Src.Range("C$2:G$100") 'Huomaa, tässä on käytetty yllä esitettyä Src, joka ilmaisee mistä välilehdestä on kyse.
- Välilehden nimi ja solu muuttujassa, objekti, set
Dim strCell As Object Set strCell = Worksheets("Välilehdennimi").Range("A10") strCell.Value = "Teksti" 'Asetetaan solulle arvo strLoadingCell = "" 'Tyhjennetään solun arvo
- Välilehden nimi ja solu muuttujassa, string, let
Dim strCell As String Let strCell = Worksheets("Välilehdennimi").Range("A10") strURL = "http://osoite/" & strCell
- Solu muuttujassa, string
Dim strCell As String Let strCell = "A1" strURL = "https://osoite/" & Sheets("Välilehdennimi").Range(strCell)
- Välilehden nimi ja solu muuttujassa, ???, ???
- Puuttuu ohje miten määritellään kun halutaisiin korvata seuraava muuttujalla: Sheets("Välilehdennimi").Cells.ClearContents
Funktio (Sub)[muokkaa]
Suomenkielisessä Excelissä on suomenkieliset funktioiden nimet. Googlen ohjeet viittaavat esim. englannin kielisiin funktionimiin. Käännöstalulukoita:
- http://excelohjeet.com/excel-funktiot-suomeksi-ja-englanniksi
- https://www.excel-function-translation.com/index.php?page=english-finnish.html
- http://www.tekstiviestit.fi/sihteeriopas/sihteeriopas-materiaali-funktiot.html
- Funktion käyttö
Public Function Funktionnimi(tuotavamuuttuja1, tuotavamuuttuja2) tuotuja muuttujia voi käyttää samoilla nimillä eikä niitä tarvitse uudestaan Dim... End Function Sub Nimi1() jotain... End Sub Sub Nimi2() Funktionnimi <-- kutsutaan suoraan fukntion nimellä Funktionnimi tuotavamuuttuja1, tuotavamuuttuja2 <-- tai lähetetään funktiolle muuttujissa tietoa Nimi1 <-- kutsutaan suoraan Subia End Sub
Jos (If)[muokkaa]
- And ja useamman Or-operaattorin yhdistäminen. Toisen vaihtoehdon useampi vaihtoehto niputetaan sulkeilla yhdeksi eli X And (Y1 Or Y2 Or Y3) Esimerkissä Src on tällä sivulla käytetty viittaus, joka kertoo mistä Excelin välilehdestä on kyse.
=If Src.Cells(i, "C") = muuttuja1 And (Src.Cells(i, "D") = muuttuja2 Or Src.Cells(i, "E") = muuttuja2) Then
- Esimerkki 1
If muuttuja1 = "" Then Exit Sub ElseIf muuttuja2 = "" And muuttuja3 <> "" Then jotain... End If
- Esimerkkinä testataan onko välilehdellä 1 oleva vuosiluku alle kolme vuotta nykyisestä vuodesta ja jos on, haetaan välilehdeltä 3 arvo solusta B1 välilehdelle 2. Ja jos yli 3 vuotta, haetaan välilehdeltä arvo solusta B2.
If (Year(Date) - Worksheets("Välilehdennimi1").Range("A1")) > 3 Then Worksheets("Välilehdennimi2").Range("A2") = Worksheets("Välilehdennimi3").Range("B1") Else: Worksheets("Välilehdennimi2").Range("A2") = Worksheets("Välilehdennimi3").Range("B2") End If
- Select, ponnahdusikkuna Kyllä, Ei, Peruuta
Select Case MsgBox("Lisätään valmis teksi, mutta tyhjennetäänkö samalla solu A1?", vbYesNoCancel) Case vbCancel Cancel = True 'peruutetaan toimenpide Case vbNo Worksheets("Välilehdennimi1").Range("A2").Value = Worksheets("Välilehdennimi2").Range("B10") Case vbYes Worksheets("Välilehdennimi1").Range("A1").ClearContents Worksheets("Välilehdennimi1").Range("A2").Value = Worksheets("Välilehdennimi2").Range("B10") End Select
Silmukka (For..Next)[muokkaa]
Dim i As Long For i = 2 To 10 jotain... Next i
Sub Makro1() If Worksheets(1).Range("A1").Value = "valittu" Then Dim i As Integer For i = 2 To 10 Worksheets(1).Range("A" & i).Value = "Teksti" & i Next i Else MsgBox "Aseta teksti valittu soluun A1" End If End Sub
With[muokkaa]
- Käyttötarkoitus 1: Arvojen syöttäminen useisiin saman objektin ominaisuuksiin.
With JokuObjekti .Koko = 1 .Korkeus =2 End With
Painike[muokkaa]
Usein painikkeita käytetään yhdessä makron kanssa, joka ohjelmoidaan Visual Basicilla (VBA). Painettaessa, tapahtuu jokin toiminto.
- Painikkeita lisätään a) ohjausobjektipainikkeena tai b) ActiveX ohjausobjektina.
- Peruskuvio on, että lisätään painike ja liitetään siihen makro.
- AciveX ohjausobjekti (komentopainike) Windows Wordissa
- Kehitystyökalut > Ohjausobjektit-ryhmässä ActiveX-komponentit valikosta komentopainike.
- Suunnittelutila Ohjausobjektit-ryhmässä on päällä, jolloin painiketta voidaan muokata. Kun se on poissa, painiketta voidaan käyttää.
- Valitse Ominaisuudet painikkeen päällä hiiren oikealla.
- Caption kohdassa aseta painikkeessa näkyvä nimi.
- Hiirellä värjätyn tekstin vieminen VBA-muuttujaan: valitse ylävalikosta painikkeen nimi, esim. CommandButton1 ja aseta TakeFocusOnClick arvoksi False. Tällöin sivulla oleva teksti voidaan värjätä ja kun painetaan painiketta, teksti siirtyy muuttujaan joka on ohjelmoitu VBA:ssa.
- Valitse Näytä koodi painikkeen päällä hiiren oikealla.
- Lisää VBA-koodi
- Ota suunnittelutila pois päältä ja painike toimii.
- Ohjausobjektipainike, lomakeohjaus ohjausobjekti (painike): Tämän voi valita useissa tapauksissa. Tätä ei välttämättä löydy Wordista.
- Kehitystyökalut > Lisää > Lomakeohjausobjetit > Painike
- Hiiren nuoli muuttuu ristikoksi, vedä painike haluamaasi kohtaan. Myöhemmin makroa voi siirrellä vapaasti ja muuttaa tekstiä.
- Avautuu makro-ikkuna > Valitse olemassa oleva jo aiemmin tehty makro ja paina 'OK' TAI kirjoita uusi nimi makrolle ja paina 'Uusi', jolloin avautuu Microsoft Visual Basic for Applications-ikkuna.
- Makrot kannattaa heti alusta alkaen nimetä kuvaavasti ja johdonmukaisesti.
- Makroja voi kirjoittaa useita samaan moduuliin, vaikka aina aukeaisi uusi moduui. <-- tarkenna
- Makro alkaa: Sub Makronnimi()
- Makro päättyy: End Sub
- Edellisten väliin tulee makron suorittama koodi, esim.
- Range("A1") = Worksheets("Välilehdennimi").Range("B1") hakee välilehdeltä 'Välilehdennimi' solusta B1 arvon/tekstin ja lisää sen soluun A1.
- Solu voidaan siis osoittaa samalla välilehdellä Range("A1") ja toisella välilehdellä Worksheets("Välilehdennimi").Range("A1") ja alue Range("A1:C100")
- Worksheets("Välilehdennimi").Range("A1").ClearContents tyhjentää solun arvon, mutta säilyttää muotoilun.
- Worksheets("Välilehdennimi").Range("A1:A10").Copy kopioi leikepöydälle alueella A1:A10 olevat arvot ja muotoilun.
- Huomaa, että jos soluissa on rivinvaihtoja (alt + enter), ne laitetaan sitaateihin. Jokainen tekstikappale kannattaa täten laittaa omaan soluun. Tyhjä rivinvaihto muodostetaan tyhjällä solulla.
- Range("A1") = Worksheets("Välilehdennimi").Range("B1") hakee välilehdeltä 'Välilehdennimi' solusta B1 arvon/tekstin ja lisää sen soluun A1.
- Paininike pitäisi toimia suoraan sitä klikatessa. Jos näin ei tapahdu, paina painikkeen päällä hiiren oikealla ja valitse Assign Macro... ja yhdistä haluttu makro painikkeeseen.
- Makroja sisältävä tiedosto tallennetaan xlsm -muodossa.
HUOM! Jos makrot ovat välilehtiin liittyvissä ikkunoissa, välilehden poistaminen TUHOAA myös sen makrot!!!
- Jos makro tallentaa esimerkiksi tilapäisen tiedoston samaan hakemistoon, jossa varsinainen taulukkotiedosto sijaitsee ja tulee path-virheilmoitus. Jos taulukkotiedosto on OneDrivessä, siirrä tiedosto suoraan tietokoneen C-hakemistoon. Muutoin säädä polkua.
- Module-ikkunassa tehdyt muutokset ovat välittömästi käytettävissä.
- Jos makrot eivät muutosten jälkeen toimi, ks. ikoniriviltä Visual Basic-editorissa onko "joku" päällä ja paina 'Reset'-ikonia. Yleensä ilmenee kun makroissa on virheitä.
- Painikkeita ja makroja voi yhdistellä myöhemmin, esim. muutettaessa nimiä painamalla hiiren oikeaa painikkeen päällä ja valitsemalla 'Liitä makro...'.
- Makroihin pääsee myös: Tools > Macro > Visual Basic Editor
- Uusi makro: Insert > Module
- Makroa voi käyttää myös solussa viittaamalla makrofunktion nimeen, esim. =FunktionNimi(A1)
- Hävinnyt Makron salasana
- Työkalut > Makro > Visual Basic Editor
- Avautuu ikkuna, jonka vasemmasta palkista avaa hakemistopuu näkyviin
- Etsi sieltä makro
Haku[muokkaa]
- Ohje puuttuu seuraavalta, tarkenna tähän.
- =JOS(ONLUKU(KÄY.LÄPI("Haettava sana";A1:A100));B1:B100;"")
- Haku soluista määrätyltä välilehdeltä kun ehto täyttyy. Kopioidaan koko löydetty rivi toiselle välilehdelle.
- Esimerkki 1
Dim Src As Worksheet, Trg As Worksheet Dim i As Long, j As Integer Dim muuttuja1 As String, muuttuja2 As String Set Src = ActiveWorkbook.Worksheets("välilehdennimi1") 'välilehti jossa tehdään haku Set Trg = ActiveWorkbook.Worksheets("välilehdennimi2") 'välilehti johon tulostetaan haun tulokset j = 5 'aloitetaan hakutulosten tulostus kohdevälilehden riviltä 5 If muuttuja1 <> "" And muuttuja2 = "sana" Then For i = 2 To 10 ' aloitetaan riviltä 2 ja lopetetaan riville 10 If Src.Cells(i, "D") = muuttuja2 Or Source.Cells(i, "E") = muuttuja2 Then 'etstiään sarakkeista D ja E Src.Rows(i).EntireRow.Copy Trg.Rows(j) 'kopioidaan sanan sisältävä koko rivi toiselle välilehdelle j = j + 1 'jos useita erilaisia hakuja, tämä säilyttää tulossivun seuraavan tyhjän rivin End If Next i End If
- Esimerkki 2. Tyhjän muuttujan hakemin saattaa kaataa Excelin!
Dim c As Range, j As Integer For Each c In Src.Range("C2:F10") 'Src ks. esimerkki 1 If c = muuttuja Then Src.Rows(c.Row).Copy Trg.Rows(j) 'Trg ks. esimerkki 1 j = j + 1 End If Next c
- Vapaasana-haku
- Hakee sanan, sanan osan tai peräkkäisten sanojen yhdistelmän
- Kutsutaan esim. toisesta Sub:sta seuraavasti: Vapaasanahaku vapaasana, j, Src, Trg, vapaahakualue
- vapaasana-muuttujassa on haettava sana, esim. ruusu
- j-muuttuja kertoo toisen välilehden seuraavan vapaan rivin, jolle löydetyn sanan koko rivi kopioidaan
- vapaahakualue on määritelty: Set vapaahakualue = Src.Range("B$2:G$100")
- Src ja Trg viittaavat välilehden nimeen, ks. toisaalla tällä sivulla.
Public Function Vapaasanahaku(vapaasana, j, Src, Trg, vapaahakualue) Dim cl As Range Dim FirstFound As String Dim sh As Worksheet Dim rivi As Variant Dim b As Range Application.FindFormat.Clear For Each b In vapaahakualue.Rows rivi = b.Row 'tallennetaan Set cl = b.Cells.Find(What:=vapaasana, _ After:=b.Cells(1, 1), _ LookIn:=xlValues, _ LookAt:=xlPart, _ SearchOrder:=xlByRows, _ SearchDirection:=xlNext, _ MatchCase:=False, _ SearchFormat:=False) If Not cl Is Nothing Then FirstFound = cl.Address Do Src.Rows(rivi).EntireRow.Copy Trg.Rows(j) j = j + 1 Set cl = b.Cells.FindNext(After:=cl) Loop Until FirstFound = cl.Address End If Next End Function
- Haku toiselta välilehdeltä ja löydetyn viereinen solu
- Käytä hakusanana koko solun riviä, esim. >results>name eikä pelkästään name
Sub HakuSivulta() Dim VL1 As Worksheet: Set VL1 = Worksheets("Välilehdennimi jossa haettava sana ja johon tulos") Dim VL2 As Worksheet: Set VL2 = Worksheets("Välilehdennimi josta haetaan") Dim FoundCell As Range: Set FoundCell = VL2.Range("A:A").Find(VL1.Range("A1").Value, LookIn:=xlValues, LookAt:=xlWhole) 'Yllä haetaan toisen välilehden sarakkeesta A sanaa joka on annettu toisella välilehdellä solussa A1 If FoundCell Is Nothing Then Set FoundCell = Nothing Set VL1 = Nothing Set VL2 = Nothing Exit Sub Else VL1.Range("A2") = FoundCell.Offset(0, 1) 'Tulostetaan soluun A2 löydetystä tiedosta oikealla olevasta solusta arvo End If Set FoundCell = Nothing Set VL1 = Nothing Set VL2 = Nothing End Sub
- Lähde, Source: ?
Google-haku, Chrome-selain[muokkaa]
- Lisää painike ja painikkeelle seuraava VBA-koodi. Huomaa, chromePolun sijaintai on eri 32 ja 64-bittisissä Windowseissa. Toimii Windows 10.
Sub GoogleHaku() Dim chromePolku As String Dim haku_ehto As String haku_ehto = Worksheets("Välilehdennimi").Range("A10") 'Missä solussa hakusanat 'haku_ehto = "Haettava teksti" jos teksti määritetään suoraan tässä koodissa haku_ehto = Replace(haku_ehto, " ", "+") chromePolku = "C:\Program Files (x86)\Google\Chrome\Application\chrome.exe" '64-bittinen Windows Shell (chromePolku & " -url http://google.ca/#q=" & haku_ehto) End Sub
Kopiointi[muokkaa]
- Rivin kopiointi välilehdeltä toiselle. Katso tarkemmin esimerkit Haku-otsikon alta, jossa for-silmukka (i) ja tulostussivun seuraavasta rivistä (j)
Src.Rows(i).EntireRow.Copy Trg.Rows(j) 'Src ja Trg viittaavat välilehden nimii, ks. toisaalla tällä Wikikko-sivulla. Src.Rows(c.Row).Copy Trg.Rows(j)
Noutaminen[muokkaa]
- VBA: Solun arvojen noutaminen välilehdeltä makroon:
Dim Src As Worksheet Dim muuttuja1 As Variant Dim muuttuja2 As String Set Src= ActiveWorkbook.Worksheets("välilehdennimi") muuttuja1 = Worksheets("välilehdennimi").Range("D5") muuttuja1 = Src.Range("D5") With Src muuttuja1 = .Range("D5") muuttuja2 = .Range("S6") End With
Numerot kirjaimiksi[muokkaa]
Excelissä ei ole valmista funktiota, jolla voisi esimerkiksi rahasummat muuttaa kirjaimiksi, joten se on kirjoitettava VBA:lla. Toimiva löytyy 8/2022 esim. https://www.extendoffice.com/documents/excel/1446-excel-convert-change-numbers-to-words.html
PDF[muokkaa]
Sub LuoPDF() Dim Src As Worksheet Dim alue As Range Dim tiedostonimi As String Set Src = ActiveWorkbook.Worksheets("välilehdennimi") Set alue = Src.Range("A2:F100") 'tulostettava alue 'Muotoillaan sivua ennen vientiä. Voi asettaa myös välilehden tulostusasetuksissa Src.PageSetup.Zoom = False Src.PageSetup.FitToPagesWide = 1 Src.PageSetup.Orientation = xlLandscape tiedostonimi = "jokunimitähän" & "_" & Format(Now(), "yymmdd_hhmm") & ".pdf" tiedostonimi = Environ("USERPROFILE") & "\Desktop\" & tiedostonimi 'tallennetaan Windowsin työpöydälle alue.ExportAsFixedFormat Type:=xlTypePDF, _ Filename:=tiedostonimi, _ Quality:=xlQualityStandard, _ IncludeDocProperties:=True, _ IgnorePrintAreas:=True, _ OpenAfterPublish:=True 'jos ei haluta aukeavan tallennuksen jälkeen, aseta False End Sub
Ponnahdusikkuna[muokkaa]
- Lisää painike ja yhdistä se seuraavaan makroon:
Sub Makron_nimi() MsgBox Worksheets("Välilehdennimi").Range("B10"), , "Ponnahdusikkunan otsikko" 'hakee tekstin annetulta välilehdeltä. End Sub
- Taulukosta haettavassa tekstissä voi tehdä rivinvaihtoja Alt + Enter
- Vaihtoehtoja:
- MsgBox "Teksti tähän"
- MsgBox "Ensimmäinen rivi" & vbNewLine & "Toinen rivi"
- MsgBox muuttujatähän
- MsgBox "Kysymys?", vbYesNoCancel, "Ponnahdusikkunann otsikko" 'Painikkeet Yes, No, Cancel
- If MsgBox("Kysymys?") _ = vbYes Then MsgBox "Vastasit Kyllä.", , "Ponnahdusikkunan otsikko" Else MsgBox "Vastasit Ei.", , "Ponnahdusikkunan otsikko" End If
- Ks. kohta 'Jos', jossa on esimerkki Kyllä, Ei, Peruuta toteutettuna Select-komennolla.
- Ilmoitus jos (If)-ehdosta:
If muuttuja1 = "" And muuttuja2 = "" Then MsgBox "Hakuehto puuttuu.", vbExclamation Exit Sub End If
Pudotusvalikko[muokkaa]
- Avaa Visual Basic-editorssa 'TämäTyökirja'-ikkuna
- Valitse Workbook ja Open
- Kirjoita seuraava:
Private Sub Workbook_Open() Worksheets("Välilehdennimi").Range("A1").Validation.Add Type:=xlValidateList, AlertStyle:=xlValidAlertStop, _ Formula1:="valinta1,valinta2,jne" End Sub
- Tallenna tiedosto > Sulje tiedosto > Avaa tiedosto > Pudotusvalikko ilmestyy soluun A1, kun sen valitsee (pieni väkänen oikeassa alakulmassa ulkopuolella solua).
- Huomaa, että tähän tehdyt muutokset vaativat aina tiedoston sulkemisen ja uudelleenavaamisen!
Rivi[muokkaa]
For Each b In vapaahakualue.Rows rivi = b.Row 'tallennetaan silmukasta meneillään olevan rivin numero ...
Solun arvon muuttaminen automaattisesti muutettaessa toista solua[muokkaa]
- Klikkaa hiiren oikealla sen välilehden nimeä ikkunan alareunassa, jossa on solu tai alue, johon tehtäessä muutos saadaa aikaan muutos jossain muualla.
- Valitse Näytä koodi
- Avautuu VBA ja ikkuna, jossa lukee Worksheet - Change
- Lisää seuraava koodi. Esimerkissä solun A1 arvon muuttaminen saa aikaiseksi, että Välilehdennimi1 solun A1 arvoksi asetetaan arvo B2 Välilehdennimi2:sta. Alue määritetään esim Range("A1:B10")
Private Sub Worksheet_Change(ByVal Target As Range) Dim KeyCells As Range Set KeyCells = Range("A1") If Not Application.Intersect(KeyCells, Range(Target.Address)) _ Is Nothing Then Sheets("Välilehdennimi1").Range("A1") = Worksheets("Välilehdennimi2").Range("B2") End If End Sub
Solun tyjentäminen[muokkaa]
Sub Tyhjenna_alue() Dim Trg As Worksheet Set Trg = ActiveWorkbook.Worksheets("välilehdennimi") Trg.Range("A5:G10").ClearContents 'tyhjennetään sisältö Trg.Range("A5:G10").ClearFormats 'tyhjennetään muotoilu End Sub
Solun värjääminen[muokkaa]
Värjää valittu solu punaisella. Lisää painike ja painikkeelle seuraava VBA-koodi.
Sub Värjää_solu() ActiveCell.Select ActiveCell.Interior.ColorIndex = 3 End Sub
- Värivaihtoehdot: https://www.excel-easy.com/vba/examples/background-colors.html
URL-osoite linkistä[muokkaa]
- Kun URL-osoite on solussa tekstin "takana"
- Kirjoita Visual Basicissa seuraava funktio ja kirjoita tyhjään soluun =TulostaURL(tähän linkin sisältävän solu)
Public Function TulostaURL(c As Range) As String On Error Resume Next GetURL = c.Hyperlinks(1).Address End Function
Vie solu lainausmerkeissä tekstitiedostoon[muokkaa]
- Esim. "teksti","teksti"
Kirjoita Visual Basicissa seuraava funktio
Sub QuoteCommaExport() ' Dimension all variables. Dim DestFile As String Dim FileNum As Integer Dim ColumnCount As Integer Dim RowCount As Integer ' Prompt user for destination file name. DestFile = InputBox("Enter the destination filename" _ & Chr(10) & "(with complete path):", "Quote-Comma Exporter") ' Obtain next free file handle number. FileNum = FreeFile() ' Turn error checking off. On Error Resume Next ' Attempt to open destination file for output. Open DestFile For Output As #FileNum ' If an error occurs report it and end. If Err <> 0 Then MsgBox "Cannot open filename " & DestFile End End If ' Turn error checking on. On Error GoTo 0 ' Loop for each row in selection. For RowCount = 1 To Selection.Rows.Count ' Loop for each column in selection. For ColumnCount = 1 To Selection.Columns.Count ' Write current cell's text to file with quotation marks. Print #FileNum, """" & Selection.Cells(RowCount, _ ColumnCount).Text & """"; ' Check if cell is in last column. If ColumnCount = Selection.Columns.Count Then ' If so, then write a blank line. Print #FileNum, Else ' Otherwise, write a comma. Print #FileNum, ","; End If ' Start next iteration of ColumnCount loop. Next ColumnCount ' Start next iteration of RowCount loop. Next RowCount ' Close destination file. Close #FileNum End Sub
JSON -tuonti Exceliin[muokkaa]
JSON-tiedostojen tuonti Exceliin ei ole ihan yksinkertainen.
JSON-esimerkki 1, YTJ[muokkaa]
Seuraavassa eräs ohje, esimerkkinä yrityksen tietojen haku YTJ:n avoimesta datasta. Windows 10. Käytetty 8/2020.
- Lähde, source: https://excelrocks.com/how-to-import-json-to-excel-using-excel-vba
- Siirrä xlsm-taulukkotiedosto OneDrivestä tietokoneen C-hakemiston juureen (toimii ainakin siellä).
- Lisää taulukkoon välilehti, jossa käsitellään haettava hakusana ja johon tulos, tässä Main, välilehden nimen voi muuttaa koodin alussa.
- Lisää taulukkoon välilehti, johon JSON-tieto tuodaan, tässä YTJ-tulokset, välilehden nimen voi muuttaa koodin alussa.
- Lisää VBA-moduuli nimeltä modjson ja siihen seuraava koodi.
- Moduulin nimen muuttaminen jälkeenpäin: VBA-editorissa paina Ctrl-R > Paina F4 > Valitse moduuli ylruudussa ja muuta nimi alaruutuun välilehdellä Alphabetic.
Option Explicit '********************************************************************** '* Code to exercise the clsJson class: * '* Read data from a URL and store to a file, * '* read the file and parse out JSON data * '* Sanjay Gour * '* https://excelrocks.com/how-to-import-json-to-excel-using-excel-vba * '********************************************************************** 'Get data from a URL and store to "\YTJ-haku_tilapäinen_poistettava.txt" in the same 'directory as the excel spreadsheet. Public Sub StoretHTTPToTextFile() Dim xmlHttp As Object Dim strReturn As String Dim strURL As String Dim strYtunnusCell As String Let strYtunnusCell = Worksheets("Main").Range("A1") 'Missä solussa annetaan y-tunnus muodossa 1234567-8 Dim strLoadingCell As Object Set strLoadingCell = Worksheets("Main").Range("A2") 'Mihin soluun ilmestyy tilapäinen "Noudetaan..." Dim strResultSheet As Object Set strResultSheet = Worksheets("YTJ-tulokset") 'Hakutulosten välilehden nimi, lisää välilehti etukäteen 'HUOM! Muuta koodiin välilehden nimi kohtiin YTJ-tulokset, mitkä eivät muutu yllä olevalla objektilla strURL = "http://avoindata.prh.fi/bis/v1/" & strYtunnusCell 'URL-osoite ilman hakusanaa strLoadingCell.Value = "Noudetaan tietoja YTJ-palvelusta..." 'osoitteesta" & strURL 'Open URL and get JSON data Set xmlHttp = CreateObject("MSXML2.ServerXMLHTTP.6.0") xmlHttp.Open "GET", strURL xmlHttp.setRequestHeader "Content-Type", "text/xml" xmlHttp.send 'Save the response to a string strReturn = xmlHttp.responseText 'save JSON text to file ExportToTextFile ActiveWorkbook.Path & "\YTJ-haku_tilapäinen_poistettava.txt", strReturn Call LoadTheTextFileAndParse strLoadingCell = "" 'Go to 'YTJ-tulokset' sheet and select the first cell strResultSheet.Activate strResultSheet.Range("A1").Select End Sub 'Import a set of JSON data (from JSON_temp.txt located 'in the same directory as this worksheet) 'and move JSON data keys to column A and JSON 'values for the keys in Column B 'of the worksheet Private Sub LoadTheTextFileAndParse() Dim intindex As Integer Dim strVar As String Dim strStatus As String Dim strErrStatus As String Dim intDebugLevel As Integer Dim clsJson As clsJson Dim strJSONTempFile As String '0 = no info '1 = debug.print status info intDebugLevel = 1 'Set the temporary JSON temp file path in the current folder strJSONTempFile = ActiveWorkbook.Path & "\YTJ-haku_tilapäinen_poistettava.txt" 'Get JSON text string from file strVar = ImportTextFile(strJSONTempFile) 'Clear old contents in spreadsheet Sheets("YTJ-tulokset").Cells.ClearContents Sheets("YTJ-tulokset").Cells.ClearFormats Sheets("YTJ-tulokset").Columns("B:B").HorizontalAlignment = xlLeft 'Set the class connection Set clsJson = New clsJson If intDebugLevel > 0 Then Debug.Print "Tila ennen noutamista: " & clsJson.err End If 'The first step is to load the JSON information 'The loaded information will then be available 'through the clsJSON.Key and clsJSON.Value data pairs clsJson.LoadTheJSONString strVar If intDebugLevel > 0 Then Debug.Print "Tila noutamisen jälkeen: " & clsJson.err Debug.Print "Noudettu " & clsJson.NumElements & " elementtiä." End If strStatus = "Noudettu " & clsJson.NumElements & " elementtiä." 'Convert status data to text Select Case clsJson.err Case -1 strErrStatus = "JSON-jonoa ei voitu noutaa." Case -2 strErrStatus = "JSON-jonoa ei voitu täydellisesti jäsentää." Case 1 strErrStatus = "JSON-jono jäsennetty." End Select 'Display status data strStatus = strStatus & Chr(10) & strErrStatus & Chr(10) & Chr(10) & _ "YTJ-tulokset on noudettu." MsgBox strStatus, vbInformation, "TIETOJEN HAKU" 'Get all the elements of the parsed JSON text and put the data in cells (in Sheets("YTJ-tulokset")) For intindex = 1 To clsJson.NumElements Sheets("YTJ-tulokset").Cells(intindex, 1).Value = clsJson.Key(intindex) Sheets("YTJ-tulokset").Cells(intindex, 2).Value = clsJson.Value(intindex) Next 'Lastly, delete the JSON_temp.txt file If Len(Dir$(strJSONTempFile)) > 0 Then Kill strJSONTempFile End Sub 'Load a text file to a string Private Function ImportTextFile(strFile As String) As String Open strFile For Input As #1 ImportTextFile = Input$(LOF(1), 1) Close #1 End Function 'Save a text string to a file Private Function ExportToTextFile(strFile As String, strText As String) As String Dim fso As Object Dim oFile As Object Set fso = CreateObject("Scripting.FileSystemObject") Set oFile = fso.CreateTextFile(strFile) oFile.WriteLine strText oFile.Close Set fso = Nothing Set oFile = Nothing End Function
- Lisää 'Main'-välilehdelle painike ja liitä siihen edellinen makro eli StoretHTTPToTextFile
- Lisää VBA-Class moduuli nimeltä clsjson Lisäys tapahtuu Insert > Class Module ja nimeä tarvittaessa uudestaan kuten yllä ohjeistettu.
Option Explicit Private strKey As Variant Private strVal As Variant Private intHMax As Integer Private lngStatus As Long Private Sub Class_Initialize() lngStatus = -1 End Sub Public Property Get err() As Long 'Status: ' 1 = JSON string has been sucessfully parsed ' -1 = JSON string has not been loaded, no results are available ' -2 = JSON string cannot be fully parsed (JSON text not fully or incorrectly formed) err = lngStatus End Property Public Property Get NumElements() As Integer NumElements = intHMax End Property Public Property Get Key(Index As Integer) As Variant If Index > UBound(strKey) Or Index < LBound(strKey) Then Key = "" Else Key = strKey(Index) End If End Property Public Property Get Value(Index As Integer) As Variant If Index > UBound(strVal) Or Index < LBound(strVal) Then Value = "" Else Value = strVal(Index) End If End Property 'This method Loads the JSON text into an array Public Sub LoadTheJSONString(JSONText As String) 'Maximum Value for Long type Const cLongMax = (2 ^ 31) - 1 Dim lngIndex As Long Dim lngContLoc As Long Dim lngLoc As Long Dim lngDelimitOffset As Long Dim lngASize As Long Dim intNoOfChecks As Integer 'Number of different control characters in JSON Dim intCheck As Integer Dim intCtrlChr As Integer Dim intObJLvl As Integer Dim intAryElement As Integer Dim intLvl As Integer Dim strID As String Dim strChr As String Dim strKeyValue As String Dim strValue As String Dim strPChar As String Dim strFoundVal As String Dim strTempString As String Dim strAKey() As String Dim strAVal() As String Dim strALvlKey(100) As String Dim blArray As Boolean 'Flag to indicate that an array has been found Dim blStringArray As Boolean 'Flag to indicate that the element in the array is a string Dim BlArrayEnd As Boolean 'Flag to indicate that the end of an array is found Dim blValue As Boolean 'Flag to indicate that a value has been found Dim blKeyAndValue As Boolean 'Found a key and value pair Dim blDebug As Boolean 'Set the flag to true if you want to see 'debug information during the loading process blDebug = True On Error GoTo ErrHandler: lngASize = 10 ReDim strAKey(lngASize) ReDim strAVal(lngASize) 'intArrayElement = 1 'initialize value 'initialize values blArray = False BlArrayEnd = False blStringArray = False 'Generate a string of control characters 'String is {[:,]}" strID = "" strID = strID & Chr(123) 'The '{' character strID = strID & Chr(91) 'The '[' character strID = strID & Chr(58) 'The ':' character strID = strID & Chr(44) 'The ',' character strID = strID & Chr(93) 'The ']' character strID = strID & Chr(125) 'The '}' character strID = strID & Chr(34) 'The '"' character intNoOfChecks = Len(strID) intObJLvl = 0 'First element in the array will be strKey(1) and strVal(1) lngIndex = 1 'As we process the JSON string it becomes shorter and 'shorter, until its all been processed Do While Len(JSONText) > 0 'Set to maximum value as default lngContLoc = cLongMax 'Find Next control character: 'Scan the text for the closest control character 'to the beginning of the remaining JSON text For intCheck = 1 To intNoOfChecks strChr = Mid(strID, intCheck, 1) lngLoc = InStr(1, JSONText, strChr, vbBinaryCompare) If (lngLoc > 0) And (lngLoc < lngContLoc) Then lngContLoc = lngLoc intCtrlChr = intCheck strPChar = strChr End If Next intCheck 'When the above For Next Loop ends we will have found 'the closest control character 'stored in intCtrlChr - an index (1 to 8) to the 'found character in strChr 'stored in lngContLoc - position of the next 'control character 'stored in strPChar - the closest next control character If blDebug = True Then Debug.Print "Parse Character: " & strPChar End If 'A control character has been found, figure out what to do by the found character If lngContLoc < cLongMax Then 'Capture the information before the control character strValue = Mid(JSONText, 1, lngContLoc - 1) 'Capture everything after the control character (the remaining JSON string) JSONText = Mid(JSONText, lngContLoc + 1, Len(JSONText)) Else 'We found the end of the JSON string Exit Do End If 'Found a number or boolean value or key (the comma) 'Handles number types in array (process value as 'string or number; not both) If (intCtrlChr = 4) Then If ((blValue = True) Or (blArray = True)) And (blStringArray = False) Then 'Found a value, and we already have key strFoundVal = ConvertStringToValue(strValue) blKeyAndValue = True 'Set the "Key and value found" flag End If 'Finding a comma resets the string found in the array blStringArray = False End If 'Start of object (The "{" character) If intCtrlChr = 1 Then intObJLvl = intObJLvl + 1 blArray = False 'An object, not an array blValue = False 'Need to find a key first If blDebug = True Then Debug.Print "Start of Object, Moved up to level" & intObJLvl End If End If 'End of of object (The "}" character) If intCtrlChr = 6 Then 'Numbers preceded by the "}" character If blValue = True Then 'Get the found value and set a flag strFoundVal = ConvertStringToValue(strValue) blKeyAndValue = True 'Set the "Key and value found" flag 'Add back a "}" character to the string so that the level can be decremented properly JSONText = "}" & JSONText Else 'No value was found, the "}" character indicates the end of this level intObJLvl = intObJLvl - 1 blValue = False 'Need to find a key first End If If blDebug = True Then Debug.Print "End of Object, Moved down to level" & intObJLvl End If End If 'Start of array (The "[" character) If intCtrlChr = 2 Then blArray = True blValue = True 'Next thing should be a value intAryElement = 1 If blDebug = True Then Debug.Print "Start of Array, Moved up to level" & intObJLvl End If End If 'End of of array (The "]" character) If intCtrlChr = 5 Then 'Parse last numeric or boolean value of an array If (blArray = True) And (blStringArray = False) Then 'Get the found value and set a flag strFoundVal = ConvertStringToValue(strValue) blKeyAndValue = True 'Set the "Key and value found" flag End If BlArrayEnd = True 'Mark that the end of the array is found blArray = False blValue = False 'Need to find a key first If blDebug = True Then Debug.Print "End of Array, Moved down to level" & intObJLvl End If End If 'Object Value start is found (The ":" character) If intCtrlChr = 3 Then blValue = True 'Start of an object value is not the end of an array BlArrayEnd = False If blDebug = True Then Debug.Print "ready to get value" End If End If 'Start of a string (the quote " character) 'Can be a key or value If intCtrlChr = 7 Then 'The start of the key or value has been found 'The next quote will end the key or value '(unless the quote has an escape character in front of it "\") lngDelimitOffset = 1 Do 'Look for the next quote character lngLoc = InStr(lngDelimitOffset, JSONText, Chr(34), vbBinaryCompare) 'If the string is zero length "" then exit the loop If lngLoc = 1 Then Exit Do End If 'Check to see if there is a delimter just before the quote 'if there is then quote is part of the string and not the end of 'the string. If Mid(JSONText, lngLoc - 1, 1) = Chr(92) Then ' The quote character has an escape character in front of it 'so this quote doesn't count. Remove the escape character. JSONText = Mid(JSONText, 1, lngLoc - 2) & Mid(JSONText, lngLoc, Len(JSONText)) 'and move the start of the check past the delimted quote lngDelimitOffset = lngLoc 'If we have a messed up JSON string where there 'is no valid closing quotes the above "If" will 'cause an error (the "Mid" statement will attempt 'to check the string starting at a position of '-1) and the code will jump to the error handling 'section. If this error didn't occur the 'Do..Loop would get stuck. Else Exit Do End If Loop 'We now have a string, find any other delimiters '(any delimited " characters have already been fixed) strTempString = FixTheJSONString(Mid(JSONText, 1, lngLoc - 1)) If (blValue = True) Or (blArray = True) Then 'The key has been previously found and this is 'the value for the key strFoundVal = strTempString 'Set the "Key and value found" flag blKeyAndValue = True If blArray = True Then 'The value is a string blStringArray = True End If Else If lngLoc > 0 Then 'We've found a key strALvlKey(intObJLvl) = strTempString If blDebug = True Then Debug.Print "Found Key:" & strALvlKey(intObJLvl) & _ " for Level: " & intObJLvl End If End If End If JSONText = Mid(JSONText, lngLoc + 1, Len(JSONText)) End If 'Found a key and value, move it to the array If blKeyAndValue = True Then If lngIndex > lngASize Then lngASize = lngASize + 100 ReDim Preserve strAKey(lngASize) ReDim Preserve strAVal(lngASize) End If strAKey(lngIndex) = "" For intLvl = 1 To intObJLvl strAKey(lngIndex) = strAKey(lngIndex) & ">" & strALvlKey(intLvl) Next intLvl 'Save last element of an array If (blArray = True) Or (BlArrayEnd = True) Then 'add the array element to the key strAKey(lngIndex) = strAKey(lngIndex) & ">" & Trim(Str(intAryElement)) 'increment the array element intAryElement = intAryElement + 1 'Reset end of array flag (Reset, when array end is found) BlArrayEnd = False End If strAVal(lngIndex) = strFoundVal If blDebug = True Then Debug.Print "Added Key:" & strAKey(lngIndex) & _ " Value: " & strAVal(lngIndex) & " index: " & lngIndex End If lngIndex = lngIndex + 1 'Increment the array blKeyAndValue = False 'Reset the "found" flag blValue = False 'Reset the "Value Found" flag End If DoEvents Loop 'Number of items found intHMax = lngIndex - 1 strKey = strAKey strVal = strAVal lngStatus = 1 'JSON sucessfully parsed Exit Sub ErrHandler: 'Error handling lngStatus = -2 'JSON Parse error 'Uncomment the next 3 lines to figure out the 'cause of the issue: 'Debug.Print VBA.err.Number 'Debug.Print VBA.err.Description 'Resume End Sub 'This function converts a string that contains formatting 'information into a string that only contains a value. 'Values can be text, integer, or floating point values. 'null is pssed back as a zero length string: "". Private Function ConvertStringToValue(strInStr As String) As String Dim intStrPos As Integer Dim strTemp As String Dim intChar As Integer 'default value strTemp = "" 'Make sure that the string does not have a zero length strInStr = " " & strInStr 'Loop through each character in the string and remove anything 'that is not alphanumeric. For intStrPos = 1 To Len(strInStr) intChar = Asc(Mid(strInStr, intStrPos, 1)) If ((intChar >= Asc("a")) And (intChar <= Asc("z"))) Or _ ((intChar >= Asc("A")) And (intChar <= Asc("Z"))) Or _ ((intChar >= Asc("0")) And (intChar <= Asc("9"))) Or _ (intChar = Asc(".")) Or (intChar = Asc("+")) Or _ (intChar = Asc("-")) Then strTemp = strTemp & Chr(intChar) End If Next intStrPos 'Values that are listed as 'null' are converted to a zero length string If InStr(1, "null", strTemp, vbTextCompare) > 0 Then strTemp = "" End If ConvertStringToValue = strTemp End Function 'This function goes through a JSON string and corrects 'delimited characters Private Function FixTheJSONString(strInput As String) As String Dim blParseComplete As Boolean Dim lngStartPos As Long Dim lngCurrentPos As Long blParseComplete = False lngStartPos = 1 Do While blParseComplete = False 'If we don't find any escape sequences then allow the loop to end blParseComplete = True 'Escaped sequence: replace \\ with \ 'look for the the specific escape sequence lngCurrentPos = InStr(lngStartPos, strInput, "\\", vbTextCompare) If lngCurrentPos > 0 Then strInput = Mid(strInput, 1, lngCurrentPos - 1) & "\" & _ Mid(strInput, lngCurrentPos + 2, Len(strInput)) 'set the status to check for another escape blParseComplete = False End If 'Escaped sequence: replace \/ with / 'look for the the specific escape sequence lngCurrentPos = InStr(lngStartPos, strInput, "\/", vbTextCompare) If lngCurrentPos > 0 Then strInput = Mid(strInput, 1, lngCurrentPos - 1) & "/" & _ Mid(strInput, lngCurrentPos + 2, Len(strInput)) 'set the status to check for another escape blParseComplete = False End If 'Escaped sequence: replace \b with a backspace 'look for the the specific escape sequence lngCurrentPos = InStr(lngStartPos, strInput, "\b", vbTextCompare) If lngCurrentPos > 0 Then strInput = Mid(strInput, 1, lngCurrentPos - 1) & Chr(8) & _ Mid(strInput, lngCurrentPos + 2, Len(strInput)) 'set the status to check for another escape blParseComplete = False End If 'Escaped sequence: replace \f with a formfeed 'look for the the specific escape sequence lngCurrentPos = InStr(lngStartPos, strInput, "\f", vbTextCompare) If lngCurrentPos > 0 Then strInput = Mid(strInput, 1, lngCurrentPos - 1) & Chr(12) & _ Mid(strInput, lngCurrentPos + 2, Len(strInput)) 'set the status to check for another escape blParseComplete = False End If 'Escaped sequence: replace \n with a newline 'look for the the specific escape sequence lngCurrentPos = InStr(lngStartPos, strInput, "\n", vbTextCompare) If lngCurrentPos > 0 Then strInput = Mid(strInput, 1, lngCurrentPos - 1) & Chr(10) & _ Mid(strInput, lngCurrentPos + 2, Len(strInput)) 'set the status to check for another escape blParseComplete = False End If 'Escaped sequence: replace \r with a carriage return 'look for the the specific escape sequence lngCurrentPos = InStr(lngStartPos, strInput, "\r", vbTextCompare) If lngCurrentPos > 0 Then strInput = Mid(strInput, 1, lngCurrentPos - 1) & Chr(13) & _ Mid(strInput, lngCurrentPos + 2, Len(strInput)) 'set the status to check for another escape blParseComplete = False End If 'Escaped sequence: replace \t with a horizontal tab 'look for the the specific escape sequence lngCurrentPos = InStr(lngStartPos, strInput, "\t", vbTextCompare) If lngCurrentPos > 0 Then strInput = Mid(strInput, 1, lngCurrentPos - 1) & Chr(9) & _ Mid(strInput, lngCurrentPos + 2, Len(strInput)) blParseComplete = False 'set the status to check for another escape End If 'Escaped sequence: replace \uXXXX with a unicode character 'look for the the specific escape sequence lngCurrentPos = InStr(lngStartPos, strInput, "\u", vbTextCompare) If lngCurrentPos > 0 Then strInput = Mid(strInput, 1, lngCurrentPos - 1) & _ ChrW$(CLng("&h" & Mid(strInput, lngCurrentPos + 2, 4))) & _ Mid(strInput, lngCurrentPos + 6, Len(strInput)) 'set the status to check for another escape blParseComplete = False End If Loop FixTheJSONString = strInput End Function
- Syötä Main-välilehden soluun A1 sellainen y-tunnus, joka löytyy YTJ-sivustolta > paina lisäämääsi painiketta > Ilmestyy soluun A2 teksti "Noudetaan..." > Ilmestyy ponnahdusikkuna > Noudettu JSON-tieto löytyy toiselta välilehdeltä. Nyt tiedosta voi hakea esimerkiksi tällä sivulla olevan ohjeen mukaan, ks. Haku toiselta välilehdeltä ja löydetyn viereinen solu.