Gå til innhold

Dynamiske tekstbokser (Word, VBA)


Anbefalte innlegg

Hei!

Jeg er ny her, så dette er mitt første innlegg.

Flott at det finnes et norsk forum om VB, det skal helt sikkert bli mye brukt! :)

 

Over til spørsmålet/problemet mitt:

Jeg holder på å lage malsystem for en bedrift. I hovedsak har jeg lagt opp til dialogboks ved oppstart av et maldokument, for å hente inn en del opplysninger som legges inn på riktige steder når man trykker Ok. (f.eks adresseinfo, tittel på dokument, møtedeltakere osv).

Holder nå på med møtereferat og står fast!

I referatet skal det komme opp en oversikt/liste over firmaer med tilhørende deltakere som deltok på møtet.

Eks:

"Firma1 Ole Olsen

Jon Jonsen

 

Firma2 Anne Hansen

Per Olsen

 

firma 3 osv osv osv"

 

I og med at man ikke vet på forhånd hvor mange rader som trengs, tenker jeg at det skal kunne opprettes et nytt firma med deltakere (to tekstbokser ved siden av hverandre) ved et klikk på f.eks. cmd-knapp"Nytt firma m/deltakere".

Jeg ønsker altså å få med dette i dialogboksen (formen) hvor brukeren fyller inn alle de andre opplysningene.

MEN, jeg skjønner ikke hvordan jeg kan få til dette. Jeg har jobbet en del med VBA, men stort sett bare på nybegynnernivå, så metoder, funskjoner osv er ikke min sterkeste side... :)

Men har en idé om at det må lages arrays på en eller måte?

Størrelsen på formen (dialogboksen) må jo også endres i forhold til hvor mange rader som blir lagt til.

Er det noen snille eksperter her, som kan hjelpe meg?

Alle slagt tips, råd, forslag til løsninger mottas med STOOOOR takk!!!

 

Hilsen fra Elin, Fredrikstad

Lenke til kommentar
Videoannonse
Annonse

I Visual Basic 6.0 kunne dette ha blitt løst ved hjelp av såkalte kontrollarrayer som er svært enkle å ha med å gjøre. Men, ettersom dette er VBA, må vi uheldigvis benytte en rekke tildels avanserte teknikker for å i det hele få det til å fungere akseptabelt.

 

Graden av kompleksitet avhenger av dynamikken i koden - hvor mye funksjonelitet du ønsker å støtte utelukkende ved få endringer av kildekoden. Dersom du eksempelvis behøver å kunne motta hendelser fra de kontroller som legges til formen, blir dette dessverre meget vanskeligere enn å kun legge til kontroller. Uansett, her følger koden til sistnevnte:

 

Public Row As New Collection

Public Function AddControl(ProgID As String, sName As String, Left As Long, Top As Long, Width As Long, Height As Long, ControlSpace As Long) As Object

   Dim objTextBox As Object

   ' Lag og legg til en kontroll
   Set objTextBox = Me.Controls.Add(ProgID, sName, True)

   ' Sett høyde og bredde på kontrollen
   objTextBox.Height = Height
   objTextBox.Width = Width

   ' Flytt kontrollen til den korrekte posisjonen
   objTextBox.Left = Left
   objTextBox.Top = Top + Height + ControlSpace

   ' Ved å anføre kontrollen i følgende variabel, kan vi med enkelhet gå gjennom alle kontrollene til ettertiden
   Row.Add objTextBox
   
   ' Returner objektet hvilket ble skapt
   Set AddControl = objTextBox

End Function

Public Sub RemoveRow(Top As Long, Optional MoveUpwards As Boolean = True, Optional ControlSpace As Long)

   Dim Tell As Long

   ' Let etter kontroller i samme rad og slett dem dersom de korresponderer til posisjonen vi leter etter
   For Tell = 1 To Row.Count
   
       ' Vi må forsikre oss at vi aldri sjekker kontroller som ikke eksisterer
       If Tell <= Row.Count Then
   
           If Row(Tell).Top = Top Then
           
               ' Slett kontrollen fra formen
               Me.Controls.Remove Row(Tell).Name
           
               ' Slett elementet i arrayen
               Row.Remove Tell
               
               ' Vi befinner oss nå en indeks under, idet denne kontrollen nå ble slettet
               Tell = Tell - 1
               
           Else
           
               ' Flytt kontrollen nedover dersom dette er angitt og nødvendig
               If MoveUpwards And Row(Tell).Top > Top Then
           
                   ' Flytt kontrollen
                   Row(Tell).Top = Row(Tell).Top - Row(Tell).Height - ControlSpace
           
               End If
           
           End If
       
       End If
   
   Next
   
End Sub

 

Legg koden ovenfor inn i formen din. Dernest inkluderer du kommandoknappene cmdAddRow og cmdRemoveRow, som du plasser på toppen av formen. Legg deretter til følgende, slik at det befinner seg nedenfor koden du la inn sist:

 


Private Sub cmdAddRow_Click()

   Dim lastPos As Long

   ' Finn posisjonen av det siste objektet, dersom vi har objekter i raden
   If Row.Count > 0 Then
       lastPos = Row(Row.Count).Top
   Else
       ' Har vi intet, benytter vi en innkodet posisjon som det første elementet vi begynne ifra
       lastPos = 14 ' Den egentlige posisjonen vil bli dette addert med ControlSpace
   End If

   ' Legg til en rad bestående av to kolonner
   AddControl "Forms.TextBox.1", "txtFirmanavn" & Row.Count + 1, 6, lastPos, (Me.Width / 2) - 9, 15, 3
   AddControl "Forms.TextBox.1", "txtDeltagere" & Row.Count + 1, (Me.Width / 2), lastPos, (Me.Width / 2) - 9, 15, 3

   ' Endre størrelsen på formen etter posisjonen på den siste kontrollen
   Me.Height = Row(Row.Count).Top + Row(Row.Count).Height + 26

End Sub

Private Sub cmdRemoveRow_Click()

   ' Fortsett kun dersom vi har noe å slette
   If Row.Count > 0 Then

       ' Slett den siste raden
       RemoveRow Row(Row.Count).Top, False
   
       ' Endre størrelsen på formen etter posisjonen på den siste kontrollen
       If Row.Count > 0 Then
           Me.Height = Row(Row.Count).Top + Row(Row.Count).Height + 26
       Else
           ' Standardstørrelsen uten noen kontroller
           Me.Height = 50
       End If
   
   End If

End Sub

 

Men, dersom du behøver lister som overskrider formens maksimale lengde (skjermstørrelsen), vil jeg anbefale å heller benytte en virkelig array, eller metoden ovenfor i samsvar med dette. En array lages som følger:

 

Dim aArray(10) As Long

 

Deretter kan du anse denne ene variabelen som 11 unike variabler. Du kan skrive og lese til dem slik:

 

aArray(0) = "Hallo?" ' Setter det første elementet
aArray(1) = "Dette" ' Setter det andre elementet
' aArray(...) = 
aArray(10) = "testes" ' Setter det siste elementet

 

Dersom du vil ha med rader og kolonner (en tabell), deklarerer du arrayen således:

 

Dim aArray(10, 10) As Long

 

Hvilket du skriver til som sådan:

 

aArray(0, 0) = "Hallo?" ' Setter det første elementet i den første raden
aArray(1, 0) = "Dette" ' Setter det første elementet i den andre raden
aArray(1, 1) = "blir" ' Setter det andre elementet i den andre raden
' aArray(...) = 
aArray(10, 10) = "testet" ' Setter det siste elementet i den siste raden

Lenke til kommentar

Tusen hjertelig takk skal du ha!!!

Nå har jeg litt å teste ut her, og kommer helt sikkert videre.

Kjempebra at du forklarer ting, da er det lettere å forstå koden også.

Jeg skal prøve meg litt fram etter forslagene dine, og vurdere om det vil lønne seg med en enklere løsning.

Du bekreftet det jeg trodde, at dette var enkelt å få til i vanlig VB, men ikke i VBA.

 

Så tusen takk, you made my day! :D

Lenke til kommentar

Opprett en konto eller logg inn for å kommentere

Du må være et medlem for å kunne skrive en kommentar

Opprett konto

Det er enkelt å melde seg inn for å starte en ny konto!

Start en konto

Logg inn

Har du allerede en konto? Logg inn her.

Logg inn nå
×
×
  • Opprett ny...