Avatar billede folj Forsker
22. februar 2014 - 22:58 Der er 7 kommentarer og
3 løsninger

Hjælp til egen function

Hej ekstert-venner !

Jeg er igang med at lave min egen function, der i funktionskaldet fåt 2 input: et udstyrsnummer elsempel "325A og et tidsstempel elsempel 2014-02-27 11:00.

Den skal bruges til at lave en beregning af hvor meget der produceres på diverse udstyr på nogle givne tidspunkter eksempelvis på "325A" kl. 2014-02-27 11:00

Funktionen gennemløber en plan i et andet sheet, hvor udstyrsnummer og start- og stop-tidsstempler er ligger.
Funktionen returnerer en værdi for produktionen hvis udstyret er i drift på det tidsstempel der forespørges om.
Men hvis udstyret ikke er i drift, returneres "#VALUE", og med den slags data (fejl) fejler min sammentælling, når jeg vil beregne den samlede produktion.

Hvordan får jeg funktionen til at returnere værdien O, når udstyret ikke er i produktion?

Der er 3 mulige værdier at returnere:
40 hvis udstyret er i opstartsfasen (de første 10 timer efter start)
95 hvis udstyret er i produktionsfasen (de første 10 timer efter start)
30 hvis udstyret er i SlowDownfasen (de sidste 5 timer iden stop)

har forsøgsvis tilføjet ern linie fæsten øverst i fukktionen til i forsøg på at få den til at returene 0 hvis ikke funktionen fandt noget...

Altså hvis ikke der blev fundet produktion på udstyret vil jeg gerne ændre den returnerede værdi fra "#VALUE" til talværdien 0
kan jeg indbygge dette i funktionen?


Function IsRunning(Tank As String, TimeStamp As Date)
Dim StartTime As Date, EndTime As Date, StartUpTime As Date
IsRunning = 0 ' returns 0 as default

  For i = 5 To Sheets("MySheet").Range("SlutRow").Row
  StartTime = Sheets("MySheet").Range("F" & i)
  EndTime = Sheets("MySheet").Range("J" & i)
  StartUpTime = StartTime + (10 / 24)' lægger 10 timer til starttid
  SlowDownTimeTime = EndTime - (5 / 24)' trækker 5 timer fra sluttid

 
    If Sheets("Gæringsplan IA").Range("C" & i) = Tank Then ' hvis udstyrsnummer passer med input
      If StartTime <= TimeStamp Then ' hvis udstyr er startet
        If EndTime >= TimeStamp Then ' hvis udstyr stadig kører
          If TimeStamp <= StartUpTime Then  ' hvis vi er under 10 timer i opstart
              IsRunning = 40
              Exit For
          Else
              IsRunning = 95
              Exit For
          End If
          If SlowDownTime > TimeStamp Then ' hvis udstyr er i fase SlowDown (sidste 5 timer)
              IsRunning = 30
              Exit For
          End If ' hvis SlowDown slutter
        End If ' hvis stadig startet slutter
      End If ' hvis startet slutter
    End If ' hvis udstyrsnummer passer med input slutter
   
  Next i
 
End Function
Avatar billede folj Forsker
23. februar 2014 - 10:48 #1
Da der her søndag stadig ikke er nogen der har budt ind med noget, har jeg selv forsøgt mig videre.

Første forsøg (vba-løsningen):
Jeg skrev ind nederst i min function:
  If IsError(IsRunning) Then
  IsRunning = "F"
  End If

MEN DET LØSTE IKKE PROBLEMET...

I stedet løste jeg problemet ved at lave fejlhåndteringen i cellen samtidig med mit funktionskald:

=IF(ISERROR(isrunning($B$1;(A16)));0;isrunning($B$1;(A16)))


Jeg forstår stadig ikke hvorfor funktionen returnerer fejl, fordi det at ingen af if-sætningerne gik i opfyldelse, durde vel ikke returnere fejl.
Det kan forekomme at den bliver foodret med at edstyrsnummer eller et tidsstempel der slet ikke matcher med det sheet data trækkes fra...
Jeg håber stadig på at kunne få hjælp til at forklare dette, og allerhelst til at klare fejlhåndteringen direkte i funktionen, således at den returnerer = eller FALSE ved fejl...

mvh Folmer
Avatar billede RogerWilco Seniormester
23. februar 2014 - 11:54 #2
Du bruger både "MySheet" og "Gæringsplan IA" som arknavne - er dette en fejl i indtastningen i Eksperten? Der burde vel være både tankbetegnelse og tider fra samme ark?

Du definerer en variabel med navnet SlowDownTimeTime, men bruger senere en SlowDownTime - endnu en trykfejl?

Idéen med at lave en default-værdi er god nok, men hvis koden fejler, bliver den nok ignoreret.

Jeg hader generelt brugen af "Exit", så den indre del af koden kunne måske laves om til noget i stil med:
  If (Sheets("Gæringsplan IA").Range("C" & i)=Tank) And (TimeStamp>=StartTime) And (TimeStamp<=EndTime) Then
    Select Case TimeStamp
      Case StartTime To StartupTime
        IsRunning=40
      Case SlowDownTime To EndTime
        IsRunning=30
      Case Else
        IsRunning=95
    End Select
  End If
Avatar billede store-morten Ekspert
23. februar 2014 - 12:53 #3
Måske:
If IsRunning = 30 Or IsRunning = 40 Or IsRunning = 95 Then
Else
  IsRunning = 0
End If
Avatar billede folj Forsker
23. februar 2014 - 13:15 #4
@RogerWilco
Ja. det er godt spottet - det er dog ikke det der skaber omtalte fejl. Det er en fejl jeg lavede da jeg formulerede mit spm. Prøvede blot at sløre mine navne med et mere neutralt sheetnavn.

Den anden, som du også spottede har jeg selv lige opdaget, da jeg ikke kunne få funktionen til at returnere det ønskede SlowDownTime-output. Jeg var sågar ved at formulere at nyt spm til eksperten.dk, og som det er typisk, mens man sidder og formulerer sit spm, og beskriver hvad man selv har testet osv. så finder man jo selv fejlen, og kunne således spare jer ekspert-hjælpere for et nyt spørgsmål.

Til dit hader generelt brugen af "Exit", så giver jeg dig ikke ret. Jeg var også gerne foruden, men her viste det sig nødvendigt. Når funktionen har fundet den række i produktionsplanen, der matcher med det forespurgte, så bliver jeg nødt til at stoppe gennemløbet, for ellers svarer den kun på om sidste række matchede forespørgslen.
Det var først da jeg så, at funktionen kun svarede på om sidste række matchede, at jeg nødtvungen måtte tilføje linierne med "Exit For"

@store-morten:
Jeg har forsøgt at tilføje en else, så der altid er en af if-sætningerne der matcher, men det løser åbenbart ikke hvis udstyrsnummeret ikke findes i planen.

Jeg vil takke Jer begge for engagementet.
Som I ser af ovenstående #1 så har jeg selv løst fejlhåndteringen på en ikke så elegant måde.
Det eneste udestående er således at klare fejlhåndteringen direkte i funktionen, således at den returnerer enten talværdien 0 eller FALSE ved fejl...
Avatar billede folj Forsker
23. februar 2014 - 16:56 #5
Så fandt jeg løsning på det sidste også...
(det med at få funktionen til at returnere talværdien 0 i stedet for fejl):


Function IsRunning(Tank As String, TimeStamp As Date)
Dim StartTime As Date, EndTime As Date, StartUpTime As Date

' øverst i funktionen placeres denne linie
On Error GoTo ErrorHandler ' hvis fejl gå til etiketten (bogmærket) "ErrorHandler"

' så kommer hele min kode til funktionen...
' kode
' kode osv

'og så nederst i funktionen kommer disse linier:
  Exit Function

ErrorHandler: ' etiketten (bogmærket) "ErrorHandler"

  IsRunning = 0 ' Funktionen returnerer talværdien 0 i stedet for fejlkode

End Function

Hvis nogen af Jer andre der har engageret Jer i mit spørgsmål vil have del i points, så kan der også blive nogle velfortjente points til Jer. Jeg opfordrer jer hermed til at smide et svar.
Avatar billede RogerWilco Seniormester
23. februar 2014 - 19:47 #6
Jeg må altså lige spørge, får du nogensinde SlowDown-værdien 30 som resultat?

Hvad angår brugen af Exit, har det været "børnelærdom" for mig, at det giver dårlig kode, da det ved evt. senere udvidelse af koden er sværere at vedligeholde.

Er der flere tanke med samme betegnelse? Hvis ikke, skulle det jo ikke være nødvendigt at lave en Exit, da der jo checkes, om tankbetegnelsen matcher argumentet.
Desuden kan man jo i if-sætningen efter for-kommandoen checke, om IsRunning<>0, så der ikke laves yderligere tildelinger til resultatet.
Avatar billede folj Forsker
23. februar 2014 - 22:17 #7
@RogerWilco
Ja, det lykkedes at får den til at returnere SlowDown-værdien også, men ikke uden videre.

Der måtte byttes om på rækkefølgen af if-sætningerne.
Når det var fundet at udstyret var i drift, og var igennem opstart, så skal jeg spørge først, om den er i SlowDown, inden jeg kan konkludere, at den er i produktionsfasen.

Jeg venter lige med at afslutte indtil store-morten evt. har smidt et svar også...

Det med tanke med samme navn, forekommer selvfølgelig ikke, men i den produktionsplan som jeg gennemløber er det samme udstyr jo i drift mange gange, blot på forskellige datoer.
Avatar billede folj Forsker
23. februar 2014 - 22:23 #8
Det med Exit Function før min ErrorHandler sikrer jo at linierne til fejlbehandling, kun brugen hvis Error-situationen opstår.

Samme system med Exit og et bogmærke, har jeg også set anvendt til andre ting, hvor man i en kode kun vil have noget til at ske hvis en betingelse er opfyldt.

Det kunne således bruges i forlængese af en if-sætning med GoTo bogmærke...
Avatar billede store-morten Ekspert
23. februar 2014 - 22:25 #9
Har godt nok ikke bidraget med meget, men du får et 'svar' :-)
Avatar billede folj Forsker
24. februar 2014 - 08:03 #10
Fordelte pointsene...

Og igen tak for Jeres engagement i problemet.
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Excel kurser for alle niveauer og behov – find det kursus, der passer til dig

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester