Kirjautuminen

Haku

Tehtävät

Keskustelu: Ohjelmointikysymykset: VBA: Excel & Visual Basic: tärkeitä peruskysymyksiä

Sivun loppuun

Queq [08.06.2006 17:13:22]

#

Elikkäs, ohjelmoin Excelin mukana tulevalla Visual Basic editorilla.

1) Onko Excelin mukana tuleva Visual Basic täysimittainen versio Visual Basicista, vaiko joku typistetty versio?

Minulla on Visual Basicissa formi (UserForm1 nimeltään), jossa on kolme Command Buttonia (CommandButton1, CommandButton2 ja CommandButton3).

Tässä niiden koodi:

Private Sub CommandButton1_Click()
 Freeze(CommandButton2)
End Sub

Private Sub CommandButton2_Click()
 MessageBox("Test")
End Sub

Private Sub CommandButton3_Click()
 MakeTable("Test",2,2)
End Sub

Tässä funktiokoodi

Function Freeze(Handle as string)
 With Handle
  .Enabled = False
 End With
End Function

Function MessageBox(Word as String)
 MsgBox Word
End Function

Function MakeTable(Name as string, x as integer, y as integer)
 Public Name()
 ReDim Name(1 to x, 1 to y)
End Function

CommandButton1. Tätä painaessa olisi tarkoitus, että CommandButton2 menee toimintakyvyttömäksi. Ja miksi se pitäisi toteuttaa funktiona? Siksi, koska tälläisiä buttoneita, jotka pitäisi helposti saada pois pelistä tulee olemaan kymmeniä. Tälläistä erroria heittää:

Compile error: With object must be user-defined type, Object, or Variant

2) Miten saan korjattu tämän ongelman?

CommandButton2. Kaikki toimii miten pitääkin (Tulee msgbox, jossa lukee "Test")

CommandButton3. Tarkoituksena olisi luoda taulukko. Ohjelmassa on n (tuntematon) määrä taulukoita, joissa tulee olemaan n määrä soluja, joten taulukoita pitäisi pystyä luomaan helposti, ilman, että niitä pitää luoda käsin koodin sisältä. CommandButton3:sta tulee tälläinen error:

Compile error:
Syntax error

3) Miten voisin korjata ongelman tai luoda taulukoita mahdollisimman helposti?

4) Miten voin tehdä Windows tyylisen file-pickerin?commdlg.dll sisältää kyllä ohjausobjektin tälläisen tekemiseen helposti, mutta en saa importattua commdlg.dll:ää millään tavalla Visual Basiciin. commdlg32.dll:n Visual Basic suostuu kyllä ottaamaan, mutta tuo taas herjaa "No valid lisenced" tai vastaavaa.

Kiitos jo etukäteen vastauksista! Olen miettinyt näitä monta tuntia, mutta en enää yksinkertaisesti keksi vastauksia kysymyksiini. Kaikkiin kysymyksiinhän ei tarvitse vastata, jos edes yhden saisin ratkaistua, olisin kiitollinen!

Antti Laaksonen [08.06.2006 18:05:04]

#

Excelin mukana ei tule kunnollista VB:tä, vaan pelkkä VBA (Visual Basic for Applications), mutta voi silläkin tehdä yhtä ja toista.

Viittaus nappiin pitää välittää näin, jotta ohjelma toimii:

Sub Himmenna(nappi As CommandButton)
    nappi.Enabled = False
End Sub

Private Sub CommandButton1_Click()
    Himmenna CommandButton1
End Sub

Kaikki taulukot voi tallentaa yhteen isoon taulukkoon tähän tapaan:

Dim tiedot(1 To 5, 1 To 1000) As Integer

Nyt käytössä on viisi taulukkoa, joissa jokaisessa on 1000 alkiota. Taulukolle ei voi antaa nimeä muuttujan sisällön perusteella. Komento Public toimii vain kooditiedoston alussa aliohjelmien ulkopuolella.

Tiedostoikkunaa voi kutsua suoraan WinAPIn kautta, mikä toimii mainiosti myös VBA:ssa:
https://www.ohjelmointiputka.net/koodivinkit/23478-vb6-commondialog-winapi-n-kautta

Queq [08.06.2006 20:14:10]

#

Kiitos! Toimii kuin rasvattu! :)

Queq [09.06.2006 17:39:05]

#

Minulla on nyt valmiina systeemi, jonka kanssa saan selville tietyn hakemiston kaikki tiedostot. Kuitenkin eri hakemistojen eri tiedostot pitäisi saada selville monta kertaa eri paikoissa koodia.

Helpointa olisi varmaankin luoda funktio tuosta hakemiston tiedostolistaajasta. Mutta, 5) kuinka funktiolla voi palauttaa vaikkapa kymmenen eri tiedoston nimen?

Yhden funktion sisällä on myös tälläinen käsky "ListBox1.AddItem Name". Tuo ei kuitenkaan toimi. 6) Miten pääsee funktion sisältä ListBoxiin käsiksi? Pitäisikö ListBox jotenkin määritellä Publiciksi, jotta siihen ja sen ominaisuuksiin pääsisi käsiksi minkä tahansa proseduurin sisältä?

Kiitos paljon avusta! :)

Blaze [09.06.2006 18:12:30]

#

Queq kirjoitti:

kuinka funktiolla voi palauttaa vaikkapa kymmenen eri tiedoston nimen?

Function Palle As String()
  Dim MJonot(10) As String
  Palle = MJonot
End Function

Queq kirjoitti:

Pitäisikö ListBox jotenkin määritellä Publiciksi, jotta siihen ja sen ominaisuuksiin pääsisi käsiksi minkä tahansa proseduurin sisältä?

Koitas Forminnimi.ListBox1.AddItem

Queq [10.06.2006 18:59:30]

#

Kiitos! Nyt toimii! 7) Onko muuten Visual Basicissa mitään valmista funktiota, millä saisi selville kuinka iso taulukko on kooltaan? Kyllähän sitä voisi aina muuttujan kautta pitää huolta taulukon koosta, mutta valmis funktio helpottaisi kyllä ihan mukavasti. :)

sooda [10.06.2006 19:03:03]

#

Count-funktio taisi olla. Ellei, niin LBound kertoo alimman solun ja UBound isoimman, niistä erotuksella.

Queq [11.06.2006 19:35:54]

#

8) Miten variant tai string tyyppisen muuttujan saa muutettua currency-tyypiseksi?

CCur on kyllä se funktio, mutta ei ainakaan itselläni toimi. Tulee vain: Run-time error '13': Type mismatch.

Tässä vähän koodia:

' fso-hässäkkää

Number = File1.ReadLine ' <- epäilen, että tuo ReadLine palauttaa jossain sopimattomassa muodossa dataa.
MsgBox CCur(Number)

Ja Number on kyllä mielestäni Currencyn rajoissa, eli ongelma ei siitä pitäisi tulla. Mutta kuitenkin tuo herjaa. :/

Queq [12.06.2006 18:20:41]

#

Sain tuon currencyn toimimaan. Nyt tuli seuraava ongelma eteen, johon en saanut vastausta monen tunnin puurtamisen jälkeenkään.

Eli, tässä vähän koodia:

Sub Draw()
    ' Draw the chart once
    Macro1
End Sub

Sub DrawAll()

    ' Draw the chart 20 times
    For i = 1 To 20
        Macro1
    Next i

End Sub


Sub Macro1()
'
    Range("A1:B10").Select
    Charts.Add
    ActiveChart.ChartType = xlLineMarkers
    ActiveChart.SetSourceData Source:=Sheets("Sheet1").Range("A1:B10"), PlotBy _
        :=xlColumns
    ActiveChart.Location Where:=xlLocationAsObject, Name:="Sheet1"
    With ActiveChart
        .HasTitle = False
        .Axes(xlCategory, xlPrimary).HasTitle = False
        .Axes(xlValue, xlPrimary).HasTitle = False
    End With
    ActiveWindow.Visible = False
End Sub

Draw():lla tulee tälläistä jälkeä http://koti.mbnet.fi/php-m/muuta/problem/1.png Kaikki toimii kuten pitääkin.

Mutta DrawAll():lla tulee tälläistä jälkeä: http://koti.mbnet.fi/php-m/muuta/problem/2.png Eli, kaikki 20 kuvaajaa on päällekäin.

Tässä on siis se pulma. Pitäisi saada kaikki kuvaajat menemään omalle sivulleen automaattisesti siten, ettei ne ole päällekäin, tähän tyyliin: http://koti.mbnet.fi/php-m/muuta/problem/3.png

9) Kuinka saan 20 kuvaajaa (charttia) automaattisesi järjestäytymään kuvan 3.png mukaisesti?

Ja asiaa vielä hieman sivuten:

10) Kuinka saan selville onko "chart"-niminen WorkSheet olemassa; tulee error, jos yrittää luoda Chart-nimistä worksheettiä ja se on jo olemassa. Yksi mahdollisuus olisi On error GoTo MakeNewSheet, mutta tämä ei ole mielestäni se paras vaihtoehto; vai onko tämä sitten ainoa vaihtoehto?

Kiitoksia avusta paljon! Itse en vaan keksi ratkaisua noihin pulmiin. :/

BadSource [13.06.2006 08:10:12]

#

9) Chartin paikka

Chartin asema määritetään Parentin kautta. Seuraava koodi lisää uuden Chartin alimmaiseksi, mutta siitä saa idean, mitä pitää tehdä.

Dim toppi As Single
Dim lefti As Single

If ActiveSheet.ChartObjects.Count > 1 Then
    With ActiveSheet.ChartObjects(ActiveSheet.ChartObjects.Count - 1)
        lefti = .Left
        toppi = .Top + .Height
    End With
Else
    lefti = 100
    toppi = 25
End If
ActiveChart.Parent.Left = lefti
ActiveChart.Parent.Top = toppi

10) Tarkistetaan löytyykö Sheet

Dim sh As Worksheet

For Each sh In ActiveWorkbook.Sheets
    If sh.Name = "Chart" Then MsgBox "Chart löytyy": Exit For
Next sh
If Not sh Is Nothing Then Set sh = Nothing

Queq [14.06.2006 16:54:58]

#

Kiitos BadSource! Tuo 10. ei kyllä toimi aivan täydellisesti, ilmeisesti teen jotain väärin (muutin tuon funktioksi). Mutta kiitos avustuksesta, nyt tiedän miten taas edetä. :)

Vielä ainakin yksi kysymys 11) Kuinka teen folder-pickerin?

Tällä hetkellä file-picker ( https://www.ohjelmointiputka.net/koodivinkit/23478-vb6-commondialog-winapi-n-kautta ) toimii hyvin, mutta pitäisi saada vastaavanlainen folder-picker käyttöön. Onnistuuko millään tavalla helposti? Yksi tapahan olisi tehdä ihan omat hakemistofunktiot ja ikkunat, mutta on kyllä aivan liian vaivalloista saatuun hyötyyn nähden (tällä hetkellä folderin path asetetaan helposti textboxin kautta). :)

BadSource [15.06.2006 06:49:22]

#

Kymppi olikin vain esimerkki, millä sait selville sivujen nimet. Siitä soveltaen sun tarpeisiin sopiva.

11) FolderBrowser

Tuosta on putkassa VB-esimerkki, jonka saa siirrettyä sellaisenaan VBA:n puolelle. Eli FolderBrowser.

Queq [15.06.2006 06:53:06]

#

Tattista vaan! Alkaa näyttää jo aika täydelliseltä tämä projektini, kiitos kuuluu myös teille kaikille neuvojille. :)


Sivun alkuun

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta