Macro's en VBA https://onlineexcelcursus.nl Sat, 20 Apr 2024 08:25:07 +0000 Joomla! - Open Source Content Management nl-nl Zelf een formule maken 6 - Telefoonnummers omzetten https://onlineexcelcursus.nl/home/excel-tips-trucs/alle-excel-versies/macros-en-vba/zelf-een-formule-maken-6-telefoonnummers-omzetten https://onlineexcelcursus.nl/home/excel-tips-trucs/alle-excel-versies/macros-en-vba/zelf-een-formule-maken-6-telefoonnummers-omzetten

In veel ERP systemen is een telefoonnummer veld vaak een 'simpel' tekst veld, zonder enige vorm van validatie. We zien telefoonnummers in het formaat 0182345678, 0182-345678, +31182345678, 0182-34.56.78, '0182345678, nummers met spaties, etc. Ik kreeg recentelijk een verzoek of daar in Excel iets mee te doen is, iemand had een download uit zijn systeem en wilde hier de telefooncentrale mee 'voeden'. Bijkomende requirement was dat de kolom landcode NL, BE of leeg kon zijn, indien leeg moest er uitgegaan worden van een NL landcode.

Met een simpele 'vervangen' functie in Excel kom je  er niet, ik moest dus kijken of ik een VBA functie kon maken ;)

Ik heb een kolom met telefoonnummers, een kolom met de landcode en een (hulp) tabel waarin ik achter de landcodes de internationale toegangsnummers / prefix zet.

De functie die ik gemaakt heb heet StripEnInternationaliseer (What's in a name..):

Excel omzetten telefoonnummer

 

De functie heeft 3 parameters:

MyRange bevat de cel met het nummer wat we om willen zetten.
MyLandcode bevat de cel met de landcode
MyLandCodeRange bevat de cellen range waarin alle landcodes met hun toegangsnummers staan

 

Public Function StripEnInternationaliseer(MyRange As Range, MyLandcode As Range, MyLandcodeRange As Range)Dim nTmpVal As StringDim nLandCode As StringDim nPrefix As String

nTmpVal = Replace(MyRange.Value, ".", "")nTmpVal = Replace(nTmpVal, "-", "")

'FF omzetten naar integer omdat we een nummer willen.. If IsNumeric(nTmpVal) Then       nTmpVal = CStr(Int(nTmpVal))End If

'LandcodenLandCode = MyLandcode.ValueIf MyLandcode = "" Then       nLandCode = "NL"End If

'Prefix opzoeken o.b.v. landcode nPrefix = Application.WorksheetFunction.VLookup(nLandCode, MyLandcodeRange, 2, False)

'Samenvoegen resultaten nTmpVal = nPrefix + nTmpVal

'En teruggeven aan VBA functie StripEnInternationaliseer = nTmpVal

End FunctionDOWNLOAD het bestand HIER

 

]]>
info@dolesoft.com (Mike Dole) Macro's en VBA Sat, 14 May 2016 18:34:14 +0000
Dynamisch Filter op datum m.b.v macro geeft problemen? https://onlineexcelcursus.nl/home/excel-tips-trucs/alle-excel-versies/macros-en-vba/dynamisch-filter-op-datum-m-b-v-macro-geeft-problemen https://onlineexcelcursus.nl/home/excel-tips-trucs/alle-excel-versies/macros-en-vba/dynamisch-filter-op-datum-m-b-v-macro-geeft-problemen
Als je met een macro en een variabele een dynamisch filter wilt maken waarbij je steeds de datum opgeeft waarop je wilt filteren heb je grote kans dat, hoewel je macro er goed uit ziet, deze als je hem draait niets 
laat zien waar je wel resultaten verwacht.
Dit wordt waarschijnlijk veroorzaakt omdat je macro in de US datum notatie gaat zoeken (MM/dd/YYYY) waar wij de datum in dd/MM/YYYY hebben staan..

Download het voorbeeldbestand hier

Hieronder 2 voorbeelden van een dynamisch filter m.b.v. VBA, in het eerste filter gebruiken we een 'gewone' string als datum om de range
$A$1:$J$30" te filteren. Je zult zien dat de resultaten hiervan niet altijd zijn zoals je verwacht:

'Deze werkt alleen als je bijvoorbeeld 05-18-13 gebruikt als datum veld
Sub FoutiefFilterOpDatum()
'

Dim tmpdate As String
tmpdate = InputBox("Datum:", "Datum", "18-05-2013")
    Selection.AutoFilter
    ActiveSheet.Range("$A$1:$J$30").AutoFilter Field:=1, Operator:= _
        xlFilterValues, Criteria2:=Array(2, tmpdate)
End Sub



Met de volgende VBA code zetten we de datum m.b.v. een eigen functie eerst om naar een seriële datum. Waarbij we Jaar, Maand en Dag uit de datum halen zodat deze altijd op de juiste volgorde vertaald worden!

'Dit filter op datum werkt altijd
Public Sub MaakDynamischFilter()

    Dim nklantnaam As String
    Dim ntmpdate As Long
    Dim ntmpdatestring As String
              

    nklantnaam = InputBox("Geef het klantnummer:", "Klantnummer", "29704")
    ntmpdatestring = InputBox("Datum:", "Datum", "1-7-2013")

    ntmpdate = CreateSerialDate(CDate(ntmpdatestring))

    Cells.Select

    Selection.AutoFilter
    Selection.AutoFilter Field:=3, Criteria1:=nklantnaam
    Selection.AutoFilter Field:=1, Criteria1:="<" & ntmpdate
    Cells.Select
End Sub

'Functie om van een gewone datum een seriële datum te maken
Function CreateSerialDate(ndate As Date) As Long

Dim dDate As Date
Dim strDate As String
Dim lDate As Long


    dDate = DateSerial(Year(ndate), Month(ndate), Day(ndate))
    lDate = dDate
    CreateSerialDate = lDate

End Function

Download het voorbeeldbestand hier



]]>
info@dolesoft.com (Mike Dole) Macro's en VBA Thu, 23 May 2013 19:17:31 +0000
Zelf een formule maken 6 - Functies met werkbladnamen https://onlineexcelcursus.nl/home/excel-tips-trucs/alle-excel-versies/macros-en-vba/zelf-een-formule-maken-6-functies-met-werkbladnamen https://onlineexcelcursus.nl/home/excel-tips-trucs/alle-excel-versies/macros-en-vba/zelf-een-formule-maken-6-functies-met-werkbladnamen

Als julliie de vorige tips en trucs over het zelf schrijven van een vba functie ook hebben gelezen en de smaak te pakken hebben dan gaan we nu wat functies bekijken die ik tegen ben gekomen waar we de werkbladnamen in gebruiken. Het voorbeeldbestand met de zelfgemaakte vba functies kun je hier downloaden!

Stappen:

Om de functies die we in ieder werkblad aan kunnen roepen toe te voegen kiezen we na het openen van een Excel / maken van een nieuwe Excel voor ALT-F11 en klikken in de menubalk bovenin op 'Invoegen - Module'. Daarna 'Kopiëren' en 'Plakken' we de functies hieronder die we willen gebruiken met uiteindelijk het volgende resultaat:

Voorbeeld functies met werkbladnaam

In het voorbeeldbestand hebben we 12 tabbladen voor de maanden in een jaar.

Huidige werkbladnaam

Geef de naam van het huidige werkblad:

Function HuidigeWerkbladNaam() As String
    Application.Volatile True
    HuidigeWerkbladNaam = Application.Caller.Parent.Name
End Function

Eerste werkbladnaam

Geef de naam van het eerste werkblad:

Function EersteWerkbladNaam() As String
    Application.Volatile True
    With Application.Caller.Parent.Parent.Worksheets
    EersteWerkbladNaam = .Item(1).Name
    End With
End Function

Deze functie kunnen we nu ook heel eenvoudig in een andere functie gebruiken. Als voorbeeld gebruiken we de functie indirect waarmee we door een combinatie te maken tussen de nieuwe functie EersteWerkbladNaam() en de celverwijzing A3 eigenlijk zeggen 'Geef me de waarde uit cel A3 van het eerste werkblad'!

=INDIRECT(EersteWerkbladNaam() & "!A3")

Huidige positie werkblad

Geef het nummer / de positie van het huidige werkblad

Function HuidigeWerkpladPositie() As Integer
    Application.Volatile True
    HuidigeWerkpladPositie = Application.Caller.Parent.Index
End Function

Toon aantal werkbladen

Deze functie geeft het totaal aantal werkbladen aan wat er in een Excel file zit

Function AantalWerkbladen() As Integer
    Application.Volatile True
    AantalWerkbladen = Application.Caller.Parent.Parent.Worksheets.Count
End Function

Laatste werkbladnaam

Toon de naam van het laatste werkblad

Function LaaststeWerkbladNaam() As String
    Application.Volatile True
    With Application.Caller.Parent.Parent.Worksheets
    LaaststeWerkbladNaam = .Item(.Count).Name
    End With
End Function

Toon de naam van het vorige werkblad t.o.v. het huidige werkblad

Dit is een handige functie waarin we de naam van het vorige werkblad ophalen, staan we op het eerste werkblad (januari in het testbestand), dan toont de formule de maand december!

Function VorigeWerkbladNaam(Optional ByVal WS As Worksheet = Nothing) As String
    Application.Volatile True
    Dim S As String
    Dim Q As String
    If IsObject(Application.Caller) = True Then
    Set WS = Application.Caller.Worksheet
    If WS.Index = 1 Then
    With Application.Caller.Worksheet.Parent.Worksheets
    Set WS = .Item(.Count)
    End With
    Else
    Set WS = WS.Previous
    End If
    If InStr(1, WS.Name, " ", vbBinaryCompare) > 0 Then
    Q = "'"
    Else
    Q = vbNullString
    End If
    Else
    If WS Is Nothing Then
    Set WS = ActiveSheet
    End If
    If WS.Index = 1 Then
    With WS.Parent.Worksheets
    Set WS = .Item(.Count)
    End With
    Else
    Set WS = WS.Previous
    End If
    Q = vbNullString
    End If
    VorigeWerkbladNaam = Q & WS.Name & Q
End Function

Ook deze functie kunnen we eenvoudig in een andere functie gebruiken. Als voorbeeld gebruiken we nogmaals de functie indirect waarmee we door een combinatie te maken tussen de nieuwe functie EersteWerkbladNaam() en de celverwijzing A3 eigenlijk zeggen 'Geef me de waarde uit cel A3 van het vorige werkblad'!

=INDIRECT(VorigeWerkbladNaam() & "!A3")

 Volgende werkblad naam

Function VolgendeWerkbladNaam(Optional WS As Worksheet = Nothing) As String
    Application.Volatile True
    Dim S As String
    Dim Q As String
    If IsObject(Application.Caller) = True Then
    Set WS = Application.Caller.Worksheet
    If WS.Index = WS.Parent.Sheets.Count Then
    With Application.Caller.Worksheet.Parent.Worksheets
    Set WS = .Item(1)
    End With
    Else
    Set WS = WS.Next
    End If
    If InStr(1, WS.Name, " ", vbBinaryCompare) > 0 Then
    Q = "'"
    Else
    Q = vbNullString
    End If
    Else
    If WS Is Nothing Then
    Set WS = ActiveSheet
    End If
    If WS.Index = WS.Parent.Worksheets.Count Then
    With WS.Parent.Worksheets
    Set WS = .Item(1)
    End With
    Else
    Set WS = WS.Next
    End If
    Q = vbNullString
    End If
    VolgendeWerkbladNaam = Q & WS.Name & Q
End Function

=INDIRECT(VolgendWerkbladNaam() & "!A3" geeft ons ook weer de waarde van A3 op het volgende werkblad.

Een andere manier om een celwaarde van een vorig werkblad te krijgen is m.b.v. de volgende functie:

Function PakCelOpVorigWerkblad(Addr As String) As Variant
    Application.Volatile True
    With Application.Caller.Parent
    If .Index = 1 Then
    RefOnPrevSheet = _
    .Parent.Worksheets(.Parent.Worksheets.Count).Range(Addr).Value
    Else
    PakCelOpVorigWerkblad = .Previous.Range(Addr).Value
    End If
    End With
End Function

We geven als parameter een tekststring mee, bijvoorbeeld: =PakCelOpVorigWerkblad("A6"). Let op de dubbele quotes om A6!
Ook hier geldt weer, staan we op het eerste werkblad, pak dan de waarde uit de cel waar naar verwezen wordt op het laatste werkblad.

Wat opvalt is dat iedere functie Application.Volatile True heeft staan, dit betekent dat de functie niet alleen herberekend moet worden als de input parameter van waarde verandert, maar dat Excel moet herberekenen bij iedere wijziging van het werkblad.

]]>
info@dolesoft.com (Mike Dole) Macro's en VBA Sun, 24 Mar 2013 20:42:44 +0000
Zelf een formule maken 5 - tekst uitvullen https://onlineexcelcursus.nl/tips-trucs/excel-tips-trucs/alle-excel-versies/macros-en-vba/zelf-een-formule-maken-4-tekst-uitvullen https://onlineexcelcursus.nl/tips-trucs/excel-tips-trucs/alle-excel-versies/macros-en-vba/zelf-een-formule-maken-4-tekst-uitvullen

We gebruiken in deze functie een range parameter, een verwijzing naar een cel 'waar we iets mee gaan doen'.


Opdracht: Excel heeft een formule om getallen op te vullen, de formule tekst(), =TEKST(A1;"000") geeft dan als resultaat als er 2 in cel A1 staat 002.
Willen we 200 of A000 dan moeten we op een andere manier te werk gaan, waarschijnlijk is er binnen Excel (een combinatie van) functies om dit te bewerkstelligen maar op het moment dat ik een dergelijke functie nodig had ben ik hem gaan bouwen:

Opdracht: Maak een formule met de volgende parameter: een cel als input,  het karakter op waar je mee wilt op- / uitvullen, de gewenste lengte en de kant waar je hem op wilt vullen (links / rechts).
   

  • Toets ALT-F11   
  • Kies Invoegen Module   
  • Plak de volgende code: 
Public Function Opvullen(ByVal DoelCel As Range, ByVal OpvullenMet As String, ByVal OpvulLengte As Integer, ByVal OpvulRichting As Integer)
Dim TmpString As String
Dim TmpChar As String
Dim i As Integer
TmpString = DoelCel.Value 'Basiswaarden vullen
i = 1
If Len(TmpString) = 0 Then 'Geen celwaarde dan gelijk uit functie gaan
    Opvullen = ""
End If
If Len(TmpString) < OpvulLengte Then
    If OpvulRichting = 0 Then '0 = links
        For i = Len(TmpString) To OpvulLengte - 1 'i is 1 tot lengte - 1
            TmpChar = TmpChar & OpvullenMet
        Next i
        TmpString = TmpChar & TmpString
    ElseIf OpvulRichting = 1 Then '1 = rechts
        For i = Len(TmpString) To OpvulLengte - 1
            TmpChar = TmpChar & OpvullenMet
        Next i
        TmpString = TmpString & TmpChar
    End If
End If
Opvullen = TmpStringEnd Function

 

Als we nu in cel A1 een A zetten dan krijgen we met de formule =Opvullen(A1;0;10;1)

A000000000


Opvullen

Deze functie kun je heel gemakkelijk verbouwen om zelf een bewerking op een cel waarde uit te voeren!

]]>
info@dolesoft.com (Mike Dole) Macro's en VBA Tue, 05 Mar 2013 20:40:21 +0000
Zelf een formule maken 4 - toon de naam van de dag https://onlineexcelcursus.nl/home/excel-tips-trucs/alle-excel-versies/macros-en-vba/zelf-een-formule-maken-4-toon-de-naam-van-de-dag https://onlineexcelcursus.nl/home/excel-tips-trucs/alle-excel-versies/macros-en-vba/zelf-een-formule-maken-4-toon-de-naam-van-de-dag

We gaan weer een stapje verder en laten nu het gebruik van 'Select Case' in een zelfgemaakte formule zien.


Opdracht: Excel heeft alleen een formule om het nummer van een (week)dag aan te geven dus voor maandag 1, dinsdag 2, etc   
ik wil graag een formule hebben die mij van een datum toont welke weekdag dit geweest is.   
Maak een formule om op basis van een datum de naam van deze dag te tonen.   
   

  • Toets ALT-F11   
  • Kies Invoegen Module   
  • Zet het volgende in de formule:   
    
Function DagNaam(WelkeDatum As Date)   
    Dim DagNummer As Integer   
    DagNummer = Weekday(WelkeDatum, vbSunday)   
    Select Case DagNummer   
        Case 1   
            DagNaam = "Zondag"   
        Case 2   
            DagNaam = "Maandag"   
        Case 3   
            DagNaam = "Dinsdag"   
        Case 4   
            DagNaam = "Woensdag"   
        Case 5   
            DagNaam = "Donderdag"   
        Case 6   
            DagNaam = "Vrijdag"   
        Case 7   
            DagNaam = "Zaterdag"   
    End Select   
End Function   
   

formule dagnaam  

 

In een select case kijken we steeds of de waarde die we 'afvragen' overeenkomt met een opgegeven waarde. In ons voorbeeld bepalen we dus wat de dagnaam is van 10 februari 2013

* Overigens is er gewoon een bestaande functie binnen Excel om hetzelfde te bereiken: =TEKST(B50;"DDDD")   

Doe mee met formules in Excel!

]]>
info@dolesoft.com (Mike Dole) Macro's en VBA Tue, 12 Feb 2013 06:02:21 +0000
Zelf een formule maken 3 - Gebruik parameters in een formule https://onlineexcelcursus.nl/tips-trucs/excel-tips-trucs/alle-excel-versies/macros-en-vba/zelf-een-formule-maken-3-gebruik-parameters-in-een-formule https://onlineexcelcursus.nl/tips-trucs/excel-tips-trucs/alle-excel-versies/macros-en-vba/zelf-een-formule-maken-3-gebruik-parameters-in-een-formule

Door parameters aan onze formule toe te voegen kunnen we vanuit het Excel werkblad waarden naar de formule sturen waarmee deze moet gaan rekenen.

Klinkt complex? is het niet!

Opdracht: maak een formule om op basis van de kilometerstanden bij het tanken en het getankte aantal liters te berekenen hoeveel   

kilometer er gemiddeld per liter is gereden:   

Stappen   

  • Toets ALT-F11   
  • Kies Invoegen Module   
  • Zet het volgende in de formule:   
Public Function KilometersPerLiter(StartKM As Integer, EindKM As Integer, Liter As Single)    
    KPL = (EindKM - StartKM) / Liter   
End Function   

Wat we doen is, na de formule naam (in onderstaand voorbeeld KilometersPerLiter) zetten we de parameters door een komma gescheiden tussen de haakjes.   
De bovenstaande formule bevat het volgende =KilometersPerLiter(100;500;45)   
100 is de kilometerstand bij de vorige tankbeurt, 500 bij de huidige tankbeurt, Liter is het aantal liters getankt bij de vorige tankbeurt.   

Let er hier op dat je bij de formule in excel ; gebruikt waar je bij het maken van de functie , gebruikt tussen de parameters

De uitkomst van de formule is: 8,888889313   

As Integer/ As Single?

Bij de parameters geven we aan wat voor soort waarde we verwachten, voor StartKM willen we een heel getal (Integer), hetzelfde geldt voor EindKM maar voor liters willen we een getal achter de komma aangeven (Single)
Excel zal een foutwaarde geven als je toch probeert om een tekst met quotes (") als paramter mee te sturen:

=KPL("honderd";500;45) --> #WAARDE

Meer hierover vindt u op deze pagina

Excel formules maken kan iedereen!

]]>
info@dolesoft.com (Mike Dole) Macro's en VBA Mon, 11 Feb 2013 21:26:51 +0000
Zelf een formule maken 2 - Gebruik variabelen in een formule https://onlineexcelcursus.nl/tips-trucs/excel-tips-trucs/alle-excel-versies/macros-en-vba/zelf-een-formule-maken-2-gebruik-variabelen-in-een-formule https://onlineexcelcursus.nl/tips-trucs/excel-tips-trucs/alle-excel-versies/macros-en-vba/zelf-een-formule-maken-2-gebruik-variabelen-in-een-formule

Door variabelen in een formule te gebruiken hebben we de mogelijkheid om hier (tijdelijk) iets in te stoppen wat we later in een berekening weer gebruiken.
Het gebruik van variabelen maakt een formule leesbaarder maar bovenal flexibeler.

Hieronder een eenvoudig voorbeeld waarbij we een formule vakantiegeld maken die de som van 2 potjes met geld (de variabelen potje1 en potje2) optelt.

Stappen

  • Toets ALT-F11
  • Kies Invoegen Module
  • Zet het volgende in de formule:
Public Function Vakantiegeld()
Dim potje1 As Integer
Dim potje2 As Integer

'We stoppen 1000 euro in potje 1
potje1 = 1000

'En 750 euro in potje 2
potje2 = 750

'Ons vakantiegeld is de som van de 2 potjes:
Vakantiegeld = potje1 + potje2
End Function


Als we vervolgens in een werkblad de formule =Vakantiegeld() zetten dan zien we de uitkomst 1750

As Integer

Je geeft bij het declareren (d.m.v. het woord Dim) altijd een gegevenstype mee wat aangeeft wat er in de variabele mag komen.
In bovenstaand verhaal is dit 'as integer' dit houdt in dat we alleen 'hele getallen' in deze variabelen kunnen parkeren.
Overigens staat Excel het volgende wel toe:

potje1 = 1000.6
De uitkomst van onze formule vakantiegeld() zou dan 1751 euro zijn, Excel rondt het bedrag af!

Excel formules maken kan iedereen!

 

 

 

 

]]>
info@dolesoft.com (Mike Dole) Macro's en VBA Mon, 11 Feb 2013 21:20:28 +0000
Zelf een formule maken 1 - De basis https://onlineexcelcursus.nl/home/excel-tips-trucs/alle-excel-versies/macros-en-vba/zelf-een-formule-maken-1-de-basis https://onlineexcelcursus.nl/home/excel-tips-trucs/alle-excel-versies/macros-en-vba/zelf-een-formule-maken-1-de-basis

Om een zelfgemaakte formule te maken doe je het volgende:

  • Toets je ALT-F11 vanuit je Excel werkblad.
  • Kies nu bovenaan in het menu voor 'Invoegen - Module'

VBA Module invoegen

Een voorbeeld van een simpele formule die een cel vult met een vaste tekst is:

Public Function simsalabim()
   simsalabim = "pilatuspas"
End Function

Merk op dat na de opening “Public Function” de naam van de functie komt (simsalabim)
Ergens in de functie moet dan altijd een waarde toegekend worden aan de naam van de functie: simsalabim = "pilatuspas"

Dit lijkt misschien wat moeilijk maar het komt er eigenlijk gewoon op neer dat de laatste zin in je functie een waarde moet geven aan (de naam van) je functie.

We doen er nog een, we maken een formule 1 + 1

Public Function EenPlusEen()
    EenPlusEen = 1 + 1
End Function

Eigenlijk doen we alles in 1 regel, we wijzen de uitkomst van 1 + 1 toe aan de formulenaam 'EenPlusEen'.

Gebruiken we deze zelfgemaakte formule in Excel dan ziet dit er als volgt uit:

Voorbeeld VBA functie

Excel formules maken kan iedereen!

]]>
info@dolesoft.com (Mike Dole) Macro's en VBA Mon, 11 Feb 2013 20:58:16 +0000