vba format cell met ALS functie

Status
Niet open voor verdere reacties.

LodewijkG

Gebruiker
Lid geworden
6 dec 2012
Berichten
98
Beste,

Ik heb een calculatie programma gemaakt met een hoofdformulier en een subformulier. In het hoofd formulier kan je kiezen uit dollars/euro's/etc. dit werkt allemaal prima. Nu wil ik graag alleen de cel weergave laten aanpassen in $XXXXX,XX bij dollars en €XXXXX,XX bij euro's. Is hier een makkelijke manier voor? Heb deze helaas nog niet kunnen vinden.

Wederom bedankt!
 
Je kunt met VBA de opmaak van een veld wel aanpassen. Je hebt in dit geval niks aan de Valuta opmaak omdat die naar je landinstellingen kijkt. De opmaak aanpassing zou ik aan de <Bij Klikken> actie van de keuzelijst hangen.
 
Hey OctaFish,

Excuus, maar ik kom er nog niet helemaal uit.

Mag ik je vragen me nog wat verder op weg te helpen?

Bij het onclick event, kan je mij wellicht in de goede richting sturen hoe de code moet worden opgebouwd? Ik kom bij het googlen naar iets dergelijks namelijk bar weinig tegen.

Wederom bedankt!
 
Laatst bewerkt:
Een tekstobject heeft de eigenschap Notatie en die kun je met VBA dus wel aanpassen. Ik heb nu even geen pc tot mijn beschikking, maar je kunt de juiste schrijfwijze makkelijk uitlezen. Als je in een tekstveld gaat staan, de eigenschappen ervan opent en in het veld Notatie klikt, kun je daarna met F1 de juiste syntax opvragen van het veld. Die gebruik je dan in de klick van de keuzelijst om even tijdelijk in een inputbox te zetten bijvoorbeeld. Elke opmaak die je wilt hebben kun je in de Notatie eigenschap maken en uitlezen. Als je alles hebt, maak je in de klick event van de keuzelijst een Select Case om alle varianten aan het tekstveld toe te te wijzen.
 
Dag OctaFish,

Bedankt! Ik ben op het volgende stukje code gestrand:

Code:
Function FormatValue() As Integer 
    Dim varEnteredValue As Variant 
 
    varEnteredValue = Forms!Survey!TaxRefund.Value 
    If IsNumeric(varEnteredValue) = True Then 
        Forms!Survey!TaxRefund.Format = "Currency" 
    Else 
        Forms!Survey!TaxRefund.Format = ">" 
    End If 
End Function

Graag wil ik toelichten wat ik probeer te bereiken:

Opbouw formulieren
1. Navigatie formulier: NvgOrder
2. Daarin heb ik als formulier: frmOrder

In frmOrder heb ik de volgende boxen:
Tekstbox: txtCommisionSolid
Combobox: cboCurrency
Nu zou ik graag bereiken dat wanneer ik frmOrder open, dat txtCommisionSolid standaard de Euro(€) layout heeft, dit is ook omdat cboCurrency standaard op Euro's staat (bij eigenschappen het standaard ID voor euro's toegewezen).
Maar dat bij het wijzigen van cboCurrency naar USD de layout veranderd naar Dollars($).

Ik vroeg mij af of dit:
1. Vanuit cboCurrency een "Na bijwerken" event op andere cellen kan doen of bij txtCommisionSolid dit bij een "Bij klikken" event moet doen.
2. Met een Iff functie kan. Bijvoorbeeld Iff(Me.cboCurrency > 1(1 is namelijk euro's en blijft in deze gelijk); Me.txtCommisionSolid.Format($#,##.##);Me.txt.CommisionSolid.Format(€#,##.##)) ik werk in dit formulier met twee wisselkoersen, euro's en dollars. Geen derde opties, maar mocht er een betere oplossing zijn waarbij dit in de toekomst wel kan worden toegevoegd zie ik dat natuurlijk graag.

Of in deze wellicht:

Code:
Function FormatValue() As Integer 
    Dim varEnteredValue As Variant 
 
    varEnteredValue = Forms!frmOrder!cboCurrency.Value 
    If IsNumeric(varEnteredValue) = "1" Then 
        Forms!Survey!TaxRefund.Format = "€#,##.##" 
    Else 
        Forms!Survey!TaxRefund.Format = "$#,##.##" 
    End If 
End Function

Maar waar kan ik dan de functie FormatValue vinden?

Ik ben bang dat ik er nog naast schiet want de code werk niet... :(
 
Dag OctaFish,

Heb de volgende oplossing gevonden.

Code:
Private Sub cboCurrency_AfterUpdate()
If Me.cboCurrency = 1 Then
    Me.txtCommisionSolid.Format = "€#,##0.00"
    Me.sfmOrder.Form.AdditionalCost.Format = "€#,##0.00"
Else
    Me.txtCommisionSolid.Format = "$#,##0.00"
    Me.sfmOrder.Form.AdditionalCost.Format = "$#,##0.00"
End If
End Sub

Kan jij mij wellicht adviseren voor een betere oplossing?
 
Ik had hooguit de Click gebruikt i.p.v. AfterUpdate. Die voegt niks toe en/of is alleen maar hinderlijk in de verwerking. Een iets betere oplossing, als je meer valuta hebt, is om Select Case te gebruiken.

Code:
Private Sub cboCurrency_AfterUpdate()
    Select Case Me.cboCurrency.Value
        Case 1
            Me.txtCommisionSolid.Format = "€ #,##0.00"
            Me.AdditionalCost.Format = "€ #,##0.00"
        Case 2
            Me.txtCommisionSolid.Format = "$ #,##0.00"
            Me.AdditionalCost.Format = "$ #,##0.00"
        Case 3
            Me.txtCommisionSolid.Format = "ƒ #,##0.00"
            Me.AdditionalCost.Format = "ƒ #,##0.00"
        Case Else
            Me.txtCommisionSolid.Format = "Currency"
            Me.AdditionalCost.Format = "Currency"
    End Select
End Sub
etc.
 
Dag OctaFish,

Ik probeer het stukje code wat je adviseert in te zetten, maar ik begrijp de case statement nog niet helemaal.

Case 1 is in deze bijvoorbeeld Id = 1
Case 2 is in deze Id = 2?

Thanks.:thumb:
 
Klopt. Ongeveer :). Met Select Case bekijk je alle mogelijke resultaten die je wilt checken. In dit geval dus de waarden die uit de keuzelijst komen. Daarbij ga ik er voor het gemak dus even van uit de je keuzelijst waarden oplevert die gebaseerd zijn op de ID's, dus getallen. Dat kan best anders zijn bij jou. Controleer dus eerst wat er uit de keuzelijst komt. Je probeert dat in je laatste codevoorbeeldje zo te zien ook, maar daar doe je het verkeerd.
Code:
If IsNumeric(varEnteredValue) = "1"
gaat namelijk altijd fout. De functie IsNumeric controleert of een waarde een getal is of niet. Zo'n vergelijking is waar of niet waar. TRUE of FALSE dus. En nooit "1". Sowieso is de vergelijking = "1" niet goed, want daarmee vertaal je het getal 1 naar de tekst 1. Een numeriek getal kan dus nooit "1" zijn, maar hooguit 1.
 
Dag OctaFish,

Goed, ik denk dat ik het principe wel begrijp, dus wanneer ik met een tabel werk met autonummering voor verschillende wisselkoersen, heb ik in deze een tabel met alleen autnummering 1 = Euro, 2 = Dollar.
In dit geval zal Case 1 dan naar Euro refereren & Case 2 dan naar Dollar?

Dus in mijn beleving:
tblCurrency.CurrencyId = 1 (is euro) met tblRate.RateId = 1 (is 1)
tblCurrency.CurrencyId = 2 (is dollar) met tblRate.RateId = 2 (is 1,11)

Met in mijn mainform een cbobox gebaseerd op RateId (omdat deze per keer veranderd) ziet de code er bijvoorbeeld als volgt uit?

Code:
Private Sub cboCurrency_AfterUpdate()
    Select Case Me.cboCurrency.Column(2).Value
        Case 1
            Me.txtCommisionSolid.Format = "€ #,##0.00"
            Me.AdditionalCost.Format = "€ #,##0.00"
        Case 2
            Me.txtCommisionSolid.Format = "$ #,##0.00"
            Me.AdditionalCost.Format = "$ #,##0.00"
        Case 3
            Me.txtCommisionSolid.Format = "ƒ #,##0.00"
            Me.AdditionalCost.Format = "ƒ #,##0.00"
        Case Else
            Me.txtCommisionSolid.Format = "Currency"
            Me.AdditionalCost.Format = "Currency"
    End Select
End Sub

:eek:
 
Waarom gebruik je nu Column(2)? Nu haal je niet de default waarde op. Doorgaans zet je die al standaarwaarde neer. En verberg je de kolom.
 
In column(1) wordt in deze de RateId (waarde van de wisselkoers) opgeslagen, Column 2 is in deze soort valuta, CurrencyId.
Ik neem aan dat je hier de 'boerenverstand' telling mee bedoeld, en dat je in de keuzelijst dus 2 kolommen hebt gezet met daarin de velden [RateID] en [CurrencyId]. Het veld [CurrencyId] komt dan wellicht uit de tabel [Currency]? Zo ja: dan zou ik in die tabel ook een veld [CurFormat] opnemen waarin je de opmaak van de verschillende valuta vastlegt. (Tekstveld dus). Je keuzelijst krijgt dan 3 kolommen: [RateID], [CurrencyId] en [CurFormat]. Je hebt dan de hele constructie niet nodig en kunt de format gelijk instellen vanaf de keuzelijst.

Maar eerst even de uitleg waarom boerenverstand in dit geval niet werkt :). Keuzelijsten hebben een 'Afhankelijke kolom'. Dat is de kolom die de waarde bevat die je wilt uitlezen uit de keuzelijst. Standaard is dat kolom 1. In bovenstaand voorbeeld is dat dus het veld [RateID]. Wil je de standaard waarde uitlezen, dan kun je volstaan met de opdracht Select Case Me.cboCurrency.Value waarbij je .Value zelfs mag weglaten. Doe ik overigens zelden, want er zijn omstandigheden waarin de code fout gaat als je dat doet. En dat risico neem ik liever niet.
Wanneer en waarom gebruik je dan Me.cboCurrency.Column(1).Value? Als je een vergelijking wilt maken met een andere kolomwaarde uit de keuzelijst dan de standaardwaarde. En daarbij is het belangrijk dat je je realiseert dat Access dan begint te tellen vanaf 0. En dus niet vanaf 1! Dus als je, weer volgens voorbeeld, niet het veld [RateID] wilt zien, maar de waarden uit [CurrencyId] of [CurFormat], dan doe je dat met resp. Me.cboCurrency.Column(1).Value en Me.cboCurrency.Column(2).Value. De waarde die je bij Column(#) invoert is dus altijd één lager dan het aantal kolommen dat je hebt, beginnend vanaf kolom 1 (Column(0)) tot kolom 5 (Column(4)).
Als kolom 1 de Afhankelijke kolom is, dan is Me.cboCurrency.Column(0).Value dus hetzelfde als Me.cboCurrency.Value. En is kolom 2 de afhankelijke kolom, dan is dit hetzelfde: Me.cboCurrency.Column(1).Value en Me.cboCurrency.Value.

Ik hoop dat het nu wat duidelijker is :). Zoals ik eerder zei, zou ik de opmaak in de tabel Currency zetten en als derde kolom toevoegen aan de keuzelijst. Dan wordt het een stuk simpeler:

Code:
Private Sub cboCurrency_Click()
     Me.txtCommisionSolid.Format = Me.cboCurrency.Column(2).Value
     Me.AdditionalCost.Format = Me.cboCurrency.Column(2).Value
End Sub

Nogmaals de tip: stop met AfterUpdate, en gebruik Click. Vele malen beter...
 
Dag OctaFish,

Bedankt voor de uitleg, het is inderdaad duidelijker. Had nog niet aan de optie gedacht om een tekstveld in de tabel bij te voegen, thanks. Er leiden zoveel wegen naar Rome... Omdat het voor mij ook de eerste keer is dat ik zoiets maak zie ik de gevolgen van wat ik doen ook nog niet in. Maar goed, dat is vaak zo bij het begin denk ik.:thumb:
 
Goedemorgen OctaFish,

Ik wilde tegen beter weten in het volgende toch nog proberen.

Code:
Private Sub Form_Load()
    Select Case [Forms]![NvgOrder]![NavigationSubform].[Form]![cboCurrency]
        Case 1
            Me.cboPrice.Format = "€ #,##0.00"
        Case 2
        Case 3
            Me.cboPrice.Format = "$ #,##0.00"
    End Select
End Sub

Maar ik krijg constant de error dat het veld na NvgOrder niet gevonden kan worden.

Het volgende heb ik allemaal al geprobeerd:
Code:
[Forms]![frmNavigation]![NavigationSubform].Form![Combo15]
 of 

Forms("NvgOrder").Controls("OrderId").Form.Controls("CurrencyId").Value

én vele variaties daarop...

Bij de volgende geeft de error aan dat het veld|1 niet kan vinden:

Code:
[Formulieren]![NvgOrder]![NavigatieSubformulier].[Form]![cboCurrency].[Value]

De volgende info had ik gevonden:
http://btabdevelopment.com/easy-way-to-remember-how-to-refer-to-subforms/
http://access.mvps.org/access/forms/frm0031.htm
http://www.access-programmers.co.uk/forums/showthread.php?t=248174

Maar dat mocht niet baten...

Navigatieformulier = NvgOrder
Subform = frmOrder
Combobox = cboCurrency

Sorry voor rommel.:confused:
 
Laatst bewerkt:
Zoveel tekst, en dan tóch net datgene niet vermelden dat je nodig hebt :). Je kunt niet naar het subformulier als formulier verwijzen, want Access herkent dat niet. Subformulieren staan altijd in een subformulierobject. En je moet dus naar het object verwijzen, en niet naar het formulier. Daarom moet je er ook altijd .Form achter zetten, om duidelijk te maken dat je de eigenschappen van een formulierobject wilt benaderen. Daarnaast is het vele malen handiger om naar het startformulier te verwijzen met Me, en niet met de formuliernaam. Korter, en per definitie ook veel minder foutgevoelig. Je hoeft de naam van je formulier maar te veranderen om te weten wat ik bedoel... Ik heb je db niet, dus maar even met een eigen formulier een voorbeeldje gemaakt:

Startformulier = fStamkaart (maar dat boeit dus eigenlijk niet, want die naam gebruik ik nooit)
Subformulier = Subformulier tDossiers (foute naam, want er zit een spatie in. Moet eigenlijk niet)
Subformulierobject = objDossiers (ik kan het wel, zonder spaties :) )
Combobox = cboMedewerker

Dan kun je op een aantal manieren verwijzen naar controls op een subformulier. Heb je er veel nodig, gebruik dan een variabele voor het subformulier. Dat werkt een stuk makkelijker. Voor één control hoeft dat uiteraard niet, maar is de code nog steeds wel makkelijker te maken.

Variant 1:
Code:
    MsgBox Forms![fStamkaart]![objDossiers].Form!InstroomID
    MsgBox Me!objDossiers.Form!medewerker

Variant 2:
Code:
Dim frm As Form
    Set frm = Me!objDossiers.Form
    MsgBox frm.InstroomID.Value
 
Dag OctaFish,

Bedankt voor je uitleg. Ik kom er nog niet uit... :(

Bedankt!
 
Laatst bewerkt:
Heb je een mail gestuurd. Wat mij betreft mag je je email adres weghalen.
 
Ik heb je probleem denk ik wel opgelost, maar dat had een paar voeten in de aarde :). Om te beginnen heb ik wat tabellen aangepast, zoals je kunt zien in de tabel [tblCurrency] waar een veld [Notatie] bij is gekomen. Dat komt nu ook terug in de query onder de keuzelijst, die van zichzelf nu geen Recordsource meer heeft; die wordt toegewezen op het formulier. De rates zelf zijn nu datum-afhankelijk. Als je dus nieuwe rates invoert, zoekt het formulier zelf de bijbehorende koers op. Om dat mogelijk te maken heb ik de einddatum van de actieve koers leeggelaten; die wordt nu dynamisch ingevuld in de query. Als die de verkeerde einddatum geeft (vandaag+1) kun je dat zelf denk ik wel aanpassen naar een betere formule. Omdat je db veel te groot blijft, ook na het verwijderen van alle onnodige plaatjes en formulieren, heb ik hem op wikisend gezet. Kijk maar eens of hij naar het zin is. Ik heb het navigatieformulier ook verwijderd (vanwege de grootte) maar dat maakt voor de functionaliteit niet uit; het formulier werkt ook op het navigatieformulier.
 
Beste OctaFish,

Bedankt dat je de tijd hebt genomen om wat verbetering door te voeren. :thumb:

Ik heb nog een aantal vragen:
1. Is er een reden waarom veld [Notation] veldlengte 50 heeft en geen 255(standaard)?
2.
die van zichzelf nu geen Recordsource meer heeft; die wordt toegewezen op het formulier.
Ik begrijp niet goed wat dit betekend
3. VBA zie ik ook heel wat wijzigingen :shocked::d
Code:
Private Sub Form_Current()
    strSQL = "SELECT RateId, Rate, ValidFrom, IIf([ValidUntill] Is Null,Date()+1,[ValidUntill]) AS ValidTo, Type, Notation FROM tblCurrency " _
        & "INNER JOIN tblCurrencyRate ON tblCurrency.CurrencyId = tblCurrencyRate.CurrencyId "
    sVeld = "[" & Me.OfferDate.ControlSource & "] = "
    sFilter = "WHERE (ValidFrom <= CDate(" & CDbl(Me.OrderDate) & ") And (IIf([ValidUntill] Is Null, Date() + 1, [ValidUntill])) >= CDate(" & CDbl(Me.OrderDate) & "));"
    strSQL = strSQL & sFilter
    Me.cboCurrency.RowSource = strSQL
    Me.txtCommisionSolid.Format = Me.cboCurrency.Column(5)
    Set frm = Me.sfmOrder.Form
    With frm
        .Form.AdditionalCost.Format = Me.cboCurrency.Column(5)
        .cboPurPrice.Format = Me.cboCurrency.Column(5)
        .SalesPrice.Format = Me.cboCurrency.Column(5)
        .FreightPerMt.Format = Me.cboCurrency.Column(5)
        .CommisionPerMt.Format = Me.cboCurrency.Column(5)
        .InsurrancePerMt.Format = Me.cboCurrency.Column(5)
        .LCcostPerMt.Format = Me.cboCurrency.Column(5)
        .CostPrice.Format = Me.cboCurrency.Column(5)
        .Margin€.Format = Me.cboCurrency.Column(5)
        .CumMargin€.Format = Me.cboCurrency.Column(5)
    End With
    Me.Repaint
End Sub

Geeft oplopende errors als ik deze invoeg. Eerst bij:
Me.txtCommisionSolid.Format = Me.cboCurrency.Column(5)
als ik dit weghaal dan bij:
.Form.AdditionalCost.Format = Me.cboCurrency.Column(5)

Voor mij overigens een beetje abra cadabra wat hier nou precies bedoeld wordt. Of is dit het stuk code waar je het over hebt bij punt 2?


Dan heb ik ook nog een popup formulier genaamd: pfmProductOrder, hoe zou ik deze ook kunnen formatten aan cboCurrency?

Wederom bedankt!
 
1. Is er een reden waarom veld [Notation] veldlengte 50 heeft en geen 255(standaard)?
Noem mij één notatiemethodiek waarbij je 255 karakters nodig hebt :). Sterker nog: ik vind 50 al veel te veel; mij lijkt 10 of 12 meer dan genoeg. Maar dat mag je zelf instellen. Gebruik nooit meer tekens dan je voor een veld nodig hebt. Een veld [Tussenvoegsels] van 255 karakters is absurd; niemand heeft er meer dan 5, dus een lengte van 10 of 12 karakters voor Tussenvoegsels is meer dan genoeg. Voor een email veld pak ik hooguit 100 karakters, Plaatsnaam 50. Maar dus nóót 255 :). Dan pak ik eerder een Memoveld, als ik veel tekst kwijt wil.

2. die van zichzelf nu geen Recordsource meer heeft; die wordt toegewezen op het formulier.
Ik bouw de meeste keuzelijsten, zeker als ze afhankelijk zijn van een waarde op een formulier, op met VBA. De keuzelijst heeft bij mij dan geen Rijbron, die krijgt de keuzelijst vanuit de gebeurtenis <Bij aanwijzen>. In het voorbeeldje zit dat nog niet helemaal goed; de keuzelijst is nog gekoppeld aan de query cboCurrency. Die moet je dus verwijderen. In in de gebeurtenis Form_Current moet je een kleine aanpassing maken:
Code:
    Me.cboCurrency.RowSource = strSQL
    Me.cboCurrency.Requery
En dan werkt het zoals ik het écht bedoelde! Ik krijg namelijk nergens foutmeldingen dus ik weet niet precies hoe je het hebt ingebouwd.

Dan heb ik ook nog een popup formulier genaamd: pfmProductOrder, hoe zou ik deze ook kunnen formatten aan cboCurrency?
Dat formulier had ik er uitgegooid, dus dat kan ik niet testen.
 
Status
Niet open voor verdere reacties.
Terug
Bovenaan Onderaan