Check alle échte Black Friday-deals Ook zo moe van nepaanbiedingen? Wij laten alleen échte deals zien
Toon posts:

[VBA-Excel] Dit moet toch sneller kunnen?

Pagina: 1
Acties:
  • 966 views sinds 30-01-2008
  • Reageer

Verwijderd

Topicstarter
Hoi mensen,

ik heb een formulier (in excel) gemaakt met daarin flink wat togglebutton's!!! (4 sessies, elke sessie 24 x Ja button, Nee Button, Nvt Button)

En elke keer als een keuze wordt gemaakt, moet er direct een resultaat komen in het scorebord.
Mijn code voor elke button ziet er dus zo uit:
Visual Basic:
1
2
3
4
5
6
7
8
9
Private Sub Ja1_Click()
 Scorebord_Click
End Sub
Private Sub Nee1_Click()
 Scorebord_Click
End Sub
Private Sub NVT1_Click()
 Scorebord_Click
End Sub


En dat gaat zo maar door voor elke knop. 8)7
Ik heb nu letterlijk een hele lange rij met al deze regels onder elkaar. Is het mogelijk om dit op een snellere manier te doen?

Alvast bedankt!

  • MichielPH
  • Registratie: Februari 2005
  • Laatst online: 14-07-2024
Als OnClick-event: =Scorebord_Click()

Je moet, om een foutmelding tegen te gaan, van Scorebord_Click een function maken!

Verwijderd

Topicstarter
Alvast vooruit: Ik heb nog betrekkelijk weinig ervaring met VBA...

met die OnClick-event bedoel je dan zoiets:
Visual Basic:
1
2
Sub OnClick-event: =Scorebord_Click()
End Sub


Of moet ik die code bij userform_load plaatsen?
Je moet, om een foutmelding tegen te gaan, van Scorebord_Click een function maken!
Visual Basic:
1
2
3
Private Sub Scorebord()
rest van de code...
End Sub

  • MichielPH
  • Registratie: Februari 2005
  • Laatst online: 14-07-2024
Excuses: Ik heb geen ervaring met VBa in combinatie met Excel

Nu ik zo rondkijk kan ik nergens vinden waar je events kan invullen, zoals je bij Access kan. Negeer daarom nog maar even al mjin reacties..

Verwijderd

Topicstarter
OK, is goed. Sowieso al bedankt voor een reactie :)
Is er misschien iemand anders nog?

  • onkl
  • Registratie: Oktober 2002
  • Laatst online: 03:53
Wat je kan doen is alle togglebuttons in een frame zetten (en die kan je ook weer onzichtbaar maken) en vervolgens maak je
Pivate Sub Frame1_click
Scorebord_click
End Sub

  • MichielPH
  • Registratie: Februari 2005
  • Laatst online: 14-07-2024
Ik betwijfel of dit kan. Waarschijnlijk wordt Frame1_OnClick alleen uitgevoerd als er geen togglebutton boven ligt. Als je dus op een togglebutton klikt, zal er niets gebeuren.

Verwijderd

Topicstarter
1- Dat werkt helaas niet. Als er togglebuttons in een frame zitten en de frame maak ik onzichtbaar, dan zijn de buttons ook niet te zien...

2- Frame1_click werkt helaas alleen als ik echt op de frame klik en de handeling moet uitgevoerd worden bij een keuze...

  • Lustucru
  • Registratie: Januari 2004
  • Niet online

Lustucru

26 03 2016

Een tikje ranzig, maar het werkt wel:
Verbind de toggle button met een cel op een (hidden) worksheet en plaats code in het onchange event van het werkblad. :Y)

Overigens lijken 288 buttons me genoeg reden om na te denken over een iets andere opzet van je formuliertje ;)

[ Voor 27% gewijzigd door Lustucru op 02-11-2005 10:28 ]

De oever waar we niet zijn noemen wij de overkant / Die wordt dan deze kant zodra we daar zijn aangeland


Verwijderd

Topicstarter
Ik heb dit formulier gemaakt voor onze callcenter.
Het is de bedoeling dat als er bij een agent wordt meegeluisterd, ze bij de 24 vragen de juiste keuze maken. En er moeten in een keer 4 sessie gehouden worden. Per keer mogen er maar 3 x NEE voorkomen. Dus daarom moet ik zoveel buttons in een formulier hebben.

Maar om terug te komen op je oplossing: Kun je me een klein beetje op weg helpen door een voorbeeldje te laten zien?

  • onkl
  • Registratie: Oktober 2002
  • Laatst online: 03:53
Niesje schreef op woensdag 02 november 2005 @ 10:24:
Een tikje ranzig, maar het werkt wel:
Verbind de toggle button met een cel op een (hidden) worksheet en plaats code in het onchange event van het werkblad. :Y)

Overigens lijken 288 buttons me genoeg reden om na te denken over een iets andere opzet van je formuliertje ;)
-1: Auw dat doet pijn aan je ogen
+2: Maar 't werkt wel :)
@ _heretic_
+2: Jaloezieopwekkend _/-\o_
+2

[ Voor 7% gewijzigd door onkl op 02-11-2005 12:18 ]


Verwijderd

ik heb op dit forum al eens voorgesteld een gebeurtenisklassemodule te gebruiken, misschien is het nuttig een echt voorbeeld te geven.
wat je dus doet is een een klassemodule aanmaken die het clickevent van zelf gekozen knoppen zal afvangen. het geheel berust op de klassemodule zelf die een verwijzing naar het type van de desbetreffende knop moet bevatten (hie reen toggleknop) dmv een withevents statement en een clickprocedure uiteraard (waarin je in dit geval de code achter scorebord_click zult moeten plaatsen).
daarnaast heb je een variabele nodig (gebruikelijk is een verzameling (collection) te gebruiken), waarin je elke geinstantieerde klassemodule plaatst, zodat ze actief blijven zolang de userform getoond wordt.
het komt er dus op neer dat voor elke knop op de userform een object geinstantieerd wordt dat de klikgebeurtenis zal afvangen.

maak een klassemodule genaamd 'KlasseKnop' met de volgende code:
Visual Basic:
1
2
3
4
5
6
7
8
9
10
11
12
13
Option Explicit

Public WithEvents Knop As MSForms.ToggleButton
Public DialoogVenster  As Object

Private Sub Knop_Click()
  'test
  MsgBox Knop.Name
  'plaats hier je scorebordcode
  'of roep de procedure in je userform aan:
  'DialoogVenster.ScoreBord
  'opgepast: in dit geval moet scorebord public zijn!!
End Sub
in je userform plaats je de volgende code:
Visual Basic:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
Option Explicit

Private KnopGebeurtenisVerzameling As Collection

Private Sub UserForm_Initialize()
  Dim EenKnop         As MSForms.Control
  Dim KnopGebeurtenis As KlasseKnop
  
  Set KnopGebeurtenisVerzameling = New Collection
  For Each EenKnop In Me.Controls
    If TypeOf EenKnop Is MSForms.ToggleButton Then
      Set KnopGebeurtenis = New KlasseKnop
      Set KnopGebeurtenis.Knop = EenKnop
      Set KnopGebeurtenis.DialoogVenster = Me
      KnopGebeurtenisVerzameling.Add KnopGebeurtenis
      Set KnopGebeurtenis = Nothing
    End If
  Next
End Sub

Private Sub UserForm_Terminate()
  Set KnopGebeurtenisVerzameling = Nothing
End Sub

Public Sub ScoreBord()
  MsgBox "scorebord"
End Sub
in de initialize gebeurtenis van de userform bepaal je welke knoppen je wil afvangen. hier worden alle togglebuttons afgevangen dmv een typeof constructie, maar je kan evengoed de naam van de knop of iets anders gebruiken om te bepalen welke knoppen aan de klassemodule gekoppeld dienen te worden.

Verwijderd

Topicstarter
Zie onder

[ Voor 166% gewijzigd door Verwijderd op 02-11-2005 13:16 ]


Verwijderd

Topicstarter
Ik ga het direct proberen! Ik hou je op de hoogte. Tnx alvast ;)

Ik heb een klasse module gemaakt en daar de code (onder jouw Knop_Click) erin gezet die normaal gesproken onder scorebord_click zat. Het formulier laad verder ook goed.
Maar toch doe ik iets verkeerd, want er komt geen resultaat als ik de buttons aanklik.

  • onkl
  • Registratie: Oktober 2002
  • Laatst online: 03:53
Werkte
Visual Basic:
1
MsgBox Knop.Name

wel goed (kwam er een box als je een knop induwde?)

Verwijderd

Topicstarter
Er gebeurde helemaal niets. De code ziet er dus als volgt uit.
Dit is de Klassenmodule:
Visual Basic:
1
2
3
4
5
6
7
8
9
10
11
Option Explicit
Public WithEvents Knop As MSForms.ToggleButton
Public DialoogVenster  As Object

Private Sub Knop_Click()

MsgBox Knop.Name

'De code die normaal gesproken onder Scorebord_click stond

End sub

En deze heb ik in de userform geplaatst
Visual Basic:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
Option Explicit
Private KnopGebeurtenisVerzameling As Collection
Private Sub UserForm_Initialize()

  Dim EenKnop As MSForms.Control
  Dim KnopGebeurtenis As KlasseKnop
   
  Set KnopGebeurtenisVerzameling = New Collection
  For Each EenKnop In Me.Controls
    If TypeOf EenKnop Is MSForms.ToggleButton Then
      Set KnopGebeurtenis = New KlasseKnop
      Set KnopGebeurtenis.Knop = EenKnop
      Set KnopGebeurtenis.DialoogVenster = Me
      KnopGebeurtenisVerzameling.Add KnopGebeurtenis
      Set KnopGebeurtenis = Nothing
    End If
  Next
End Sub
Private Sub UserForm_Terminate()
  Set KnopGebeurtenisVerzameling = Nothing
End Sub 

  • onkl
  • Registratie: Oktober 2002
  • Laatst online: 03:53
Visual Basic:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
Private Sub UserForm_Initialize() 

  Dim EenKnop As MSForms.Control 
  Dim KnopGebeurtenis As KlasseKnop 
    
  Set KnopGebeurtenisVerzameling = New Collection 
  For Each EenKnop In Me.Controls 
    If TypeOf EenKnop Is MSForms.ToggleButton Then 
      Set KnopGebeurtenis = New KlasseKnop 
      Set KnopGebeurtenis.Knop = EenKnop 
      Set KnopGebeurtenis.DialoogVenster = Me 
      KnopGebeurtenisVerzameling.Add KnopGebeurtenis 
      Set KnopGebeurtenis = Nothing 
    End If 
  Next 
  MsgBox KnopGebeurtenisVerzameling.Count

End Sub 
Private Sub UserForm_Terminate() 
  Set KnopGebeurtenisVerzameling = Nothing 

Kan je regel 16 eens toevoegen? Er zou dan bij het laden een msgbox moeten verschijnen met het aantal controls wat in de collectie is opgenomen.

Verwijderd

Topicstarter
Krijg een msgbox met de waarde 0.

  • onkl
  • Registratie: Oktober 2002
  • Laatst online: 03:53
Waarschijnlijk probeert de collectie een ander type knoppen (Togglebutton) in te laden dan wat jij gebruikt.
Je kan kijken welk type jou controls zijn door in de formulier ontwerpweergave de knop aan te klikken en dan bij de eigenschappen te kijken wat er in de dropdown achter de naam staat.
waarschijnlijk
CommandButton: gewone knop
ToggleButton: Aan/uit knop
OptionButton: Zo'n ronde radiobutton/checkbox
Je moet even het goede type invullen in zowel de class module als de userform. Die msgbox moet het aantal knoppen op je formulier geven.

[ Voor 7% gewijzigd door onkl op 02-11-2005 14:15 ]


Verwijderd

Topicstarter
Stom stom stom, je hebt gelijk.
Het zijn optionbuttons. Dit aangepast en hij kwam idd met 288 Buttons.

Maar toen kwam het volgende probleem:
Een variabele is niet gedefinieerd en stopte bij Ja1...

Visual Basic:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Dim WerkbladNaam As String, Cijfer As String, GemaakteFout As String, ScoreWaarde As String
Dim Ja As Double, Nee As Double, NVT As Double
Dim AgentNaam, X

WerkbladNaam = Beoordeling.AgentNaam
Ja = 0
Nee = 0
NVT = 0

Dim Ja_Aantal, Nee_Aantal, NVT_Aantal

Ja_Aantal = Array(Ja1, Ja2, Ja3, Ja4, Ja5, Ja6, Ja7, enz)
Nee_Aantal = Array(Nee1, Nee2, Nee3, Nee4, Nee5, Nee6, Nee7,enz)
NVT_Aantal = Array(NVT1, NVT2, NVT3, NVT4, NVT5, NVT6, NVT7, enz)
 

  • onkl
  • Registratie: Oktober 2002
  • Laatst online: 03:53
Het verbaast me niet heel erg dat dat niet werkt.
Je hebt Ja1 nergens gedefinieerd. (Dim)
Maar, wat wil je doen met deze arrays? Wat voor een data wil je erin stoppen? Misschien is het handig even te googlen hoe je in Excel met array's omgaat.

Verwijderd

Topicstarter
Nou, hiervoor werkte het wel met die array.
Die ja1,ja2 enz. dat zijn de namen van die optionbuttons.

Die array had ik gemaakt om de daarna te controleren bij welke vraag de agent op ja/nee/nvt had gedrukt.

  • onkl
  • Registratie: Oktober 2002
  • Laatst online: 03:53
Ok, noem
nvt: 0
nee: 1
ja: 2
(bijvoorbeeld)
Dan kan je een array maken:
Dim antwoorden(1 to 4, 1 to 24)
Waarin het eerste getal je sessie is en het tweede getal het antwoord.
Vervolgens kan je een functie maken die je userform uitleest:
Visual Basic:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
Public Sub uitlezen(ByVal sessie As Integer, scherm as Userform)
Dim knop As Control
Dim tekst As String
Dim nummer As Integer
For Each knop In scherm.Controls
    'testen of het een optionbutton is
    If TypeOf knop Is MSForms.OptionButton Then
        If knop.Value = True Then
            If IsNumeric(Mid(knop.Name, Len(knop.Name) - 1)) Then
                 'het eennalaatste teken is een cijfer.
                 tekst = Left(knop.Name, Len(knop.Name) - 2)
                 nummer = CInt(Right(knop.Name, 2))
             Else
                 'het eennalaatste teken is een letter.
                 tekst = Left(knop.Name, Len(knop.Name) - 1)
                 nummer = CInt(Right(knop.Name, 1))
             End If 'isnumeriek
             Select Case tekst
             Case "Ja"
                 antwoorden(sessie, nummer) = 2
              Case "Nee"
                 antwoorden(sessie, nummer) = 1
             Case "NVT"
                 antwoorden(sessie, nummer) = 0
            End Select
        End If 'true
    End If
Next knop
End Sub

Om nu het scherm uit te lezen bij bijv. sessie 1 type je in je klassemodule, _onclick

uitlezen 1, DialoogVenster

en het resultaat van sessie 1, vraag 1 kan je opvragen door:
msgbox antwoorden(1,1)

Check overigens even de spelling in regel 19,21 en 23, die is Case sensitive.

[ Voor 5% gewijzigd door onkl op 02-11-2005 15:39 ]


Verwijderd

Topicstarter
_/-\o_ Tnx Onkl,

ik ga het direct uitproberen. Ik laat je weten hoe het gaat.

Verwijderd

Topicstarter
Ik heb het zo geprobeerd, en krijg de eerste fout (Sub of Function is niet gedefinieerd) bij:
Visual Basic:
1
2
Case "Ja" 
antwoorden(sessie, nummer) = 2

Nu heb ik antwoorden gedefinieerd (Dim) en daarna stopte hij helaas maar dan met de melding: Typen komen niet overeen.

  • onkl
  • Registratie: Oktober 2002
  • Laatst online: 03:53
Heb je het gedefinieerd met
Visual Basic:
1
Dim antwoorden(1 to 4, 1 to 24)
?

Verwijderd

Topicstarter
Euuhh... Bij deze |:(
Ik ga nu eens ff kijken hoe ik het op deze manier kan wegschrijven in een excel sheet.
Heb er namelijk ook een functie in gebouwd dat het resultaat later weer oproepbaar is.
Heel erg bedankt Onkl. _/-\o_
Ik ga deze codes eens goed bestuderen met de Help om ze volledig te snappen.

  • Lustucru
  • Registratie: Januari 2004
  • Niet online

Lustucru

26 03 2016

Tsja, als het toch gaat wegschrijven in een sheetje dan zou ik nog een keer kijken naar de eigenschap controlsource van je optionbox. Daarmee stel je in dat de waarde van je boxje direct in een sheet wordt gezet.

Waarmee ik niks af wil doen aan de oplossing :) van _heretic_, btw.

De oever waar we niet zijn noemen wij de overkant / Die wordt dan deze kant zodra we daar zijn aangeland


  • onkl
  • Registratie: Oktober 2002
  • Laatst online: 03:53
Met^^, hoe warm ik diep van binnen wordt voor al die dankbaarheid, iedereen die een beetje VBA kan prutsen komt om een gegeven moment op hetgeen ik je heb voorgesteld. _Heretic_ heeft mij er weer wat bijgeleerd, dus, als we dan toch een dankjewel sectie inlassen(hoe ongebruikelijk ook alhier), _/-\o_ @heretic

[ Voor 6% gewijzigd door onkl op 02-11-2005 19:52 ]


Verwijderd

onkl schreef op woensdag 02 november 2005 @ 19:51:
Met^^, hoe warm ik diep van binnen wordt voor al die dankbaarheid, iedereen die een beetje VBA kan prutsen komt om een gegeven moment op hetgeen ik je heb voorgesteld. _Heretic_ heeft mij er weer wat bijgeleerd, dus, als we dan toch een dankjewel sectie inlassen(hoe ongebruikelijk ook alhier), _/-\o_ @heretic
wel het doet deugd om dat te horen, en dat meen ik. ik heb al eerder op forums gemerkt dat een goed voorbeeld met een redelijke verklaring meer inspireert dan alleen maar een uitstekende verklaring of een goede hint. het activeert meer.

maar hier toch nog een poging om het oorspronkelijke TS probleem op te lossen, nadat ik het zinnetje
osp schreef:...elke keer als een keuze wordt gemaakt, moet er direct een resultaat komen in het scorebord...
nog eens gelezen had:

(ik maak het me tss haakjes graag moeilijk met "option explicit" dat variabeledimensionering verplicht maakt, je kan dit natuurlijk weglaten)
Visual Basic:
1
2
3
4
5
6
7
8
Option Explicit

Public WithEvents Knop As MSForms.OptionButton
Public DialoogVenster  As Object

Private Sub Knop_Change()
  DialoogVenster.ScoreBord
End Sub
dus telkens als er een knop wijzigt, wordt de scorebord routine van de userform aangeroepen. deze zal het aantal ja's, nee's en nvt's tellen:
Visual Basic:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
Option Explicit

Private KnopGebeurtenisVerzameling As Collection

Private Sub UserForm_Initialize()
  Dim EenKnop         As MSForms.Control
  Dim KnopGebeurtenis As KlasseKnop
  
  Set KnopGebeurtenisVerzameling = New Collection
  For Each EenKnop In Me.Controls
    If TypeOf EenKnop Is MSForms.OptionButton Then
      Set KnopGebeurtenis = New KlasseKnop
      Set KnopGebeurtenis.Knop = EenKnop
      Set KnopGebeurtenis.DialoogVenster = Me
      KnopGebeurtenisVerzameling.Add KnopGebeurtenis
      Set KnopGebeurtenis = Nothing
    End If
  Next
End Sub

Private Sub UserForm_Terminate()
  Set KnopGebeurtenisVerzameling = Nothing
End Sub

Public Sub ScoreBord()
  Dim AantalJa    As Integer
  Dim AantalNee   As Integer
  Dim AantalNVT   As Integer
  Dim KnopWaarde  As Integer
  Dim TelKnop     As KlasseKnop
  
  AantalJa = 0
  AantalNee = 0
  AantalNVT = 0
  For Each TelKnop In KnopGebeurtenisVerzameling
    KnopWaarde = Abs(CInt(TelKnop.Knop.Value))
    Select Case UCase(Left(TelKnop.Knop.Name, 2))
      Case "JA"
        AantalJa = (AantalJa + KnopWaarde)
      Case "NE"
        AantalNee = (AantalNee + KnopWaarde)
      Case "NV"
        AantalNVT = (AantalNVT + KnopWaarde)
    End Select
  Next
  Set TelKnop = Nothing
  lblAantalJa.Caption = CStr(AantalJa)
  lblAantalNee.Caption = CStr(AantalNee)
  lblAantalNVT.Caption = CStr(AantalNVT)
End Sub
ik ga hierbij vanuit dat het scorebord drie labels bevat, lblAantalJa, -Nee & -NVT. hier kun je dan opnieuw handig gebruik maken van de verzameling om de waardes van alle optionbuttons te testen en op te tellen. in VBA is het heel handig om met een for each de collection af te lopen, en de klassemodule die gedefinieerd is geeft uiteraard ook toegang tot de eigenschappen van het optionbutton object.

Verwijderd

Topicstarter
@ _Heretic_
Ik lees je post nu pas en ik heb inderdaad 2 labels (hidden trouwens) die bijhouden hoevaak welke keuze wordt gemaakt. Ik ga deze code ff bestuderen en toepassen. Tnx ;)
Pagina: 1