German Wieso werden die Routinen von unten nach oben abgearbeitet?

Hallo,

ich bin schon zum Beginn über eine Eigenart gestoßen, welche ich mir nicht erklären kann.

B4X:
Sub Button1_Click
    Dim I As Int
    For I=1 To 4
        xui.MsgboxAsync("Eintrag Nummer " & I, "Schleifenaufruf")
    Next
    
    xui.MsgboxAsync("Erster Eintrag", "Nr 1")
    xui.MsgboxAsync("Zweiter Eintrag", "Nr 2")
    xui.MsgboxAsync("Dritter Eintrag", "Nr 3")
    xui.MsgboxAsync("Vierter Eintrag", "Nr 4")
End Sub
Diesen Code habe ich mal in ein Click-Ereignis eines Buttons geschrieben. Nach dem Starten sehen ich diese Reihenfolge:
Vierter Eintrag / Nr 4
Dritter Eintrag / Nr 3
Zweiter Eintrag / Nr 2
Erster Eintrag / Nr 1


Auch die Schleife arbeitet es so ab.

Eintrag Nummer 4
Eintrag Nummer 3
Eintrag Nummer 2
Eintrag Nummer 1


Ich glaube nicht, dass ich von oben nach unten und hinten nach vorn denken muss. Was läuft da falsch?

Ich bin für jede Hilfe dankbar!

Im Netzt habe ich nichts gefunden. Das weiß ich ja nicht mal, was ich als Suchbegriff eingeben muss.

Danke Lothar
 

DonManfred

Expert
Licensed User

Zusätzlich ein Tutorial wie man MsgboxAsync korrekt einsetzt.
 
Hallo DM,

ich sehe gerade ein, dass mir B4A vielleicht doch zu viel Stress ist. Es ist mir doch zu viel, wegen eines kleinen Problems Mega viel Seiten in einer Sprache durchzuarbeiten, welche ich nur unvollständig verstehe - Sorry!

Ich beherrsche zwar relativ gut Visual Basic, VB.NET, C++, EMbedded, Pythhon u.a., aber B4A ist mir ohne richtige Tutorials in Deutsch doch zu kompliziert.
Es ist mir nicht möglich, eine Sprache nur mit Hilfe eines Forums zu lernen, (Schade)

Eigentlich wollte ich in diese Materie nur mal reinschauen. Leider scheitere ich daran. Vielleicht sollte man als Oldie nicht mehr alles verstehen wollen.

Ich danke allen die sich meiner Probleme angenommen haben.
Viel Spaß noch an alle, die B4A verstehen.

Viele liebe Grüße Lothar

(Leider weiß ich immer noch nicht, warum sich die Routine so verhält. Beide Threads habe ich mir zwar durchgelesen, verstehe sie aber nicht 100%ig in meinem Zusammenhang. Sorry)
 
Last edited:

Midimaster

Active Member
Licensed User
also die 4 Messageboxen werden alle gleichzeitig gezeichnet, weil du sie als Async startest. Da wartet die zweite nicht, bis die erste vom User wieder zugemacht wurde.

Nun sind die also alle gleichzeitig gemalt worden, natürlich in der Reihenfolge: erste, zweite, dritte und am Schluß die vierte. Und da die ja alle voreinander an die gleiche Stelle gemalt werden, siehst Du natürlich die vierte zu vorderst. die klickst du weg, dann bleiben nur noch drei am Bildschirm. Von denen jetzt die dritte an vorderster Stelle liegt. Deshalb hast Du den Eindruck die Boxen würden in der Reihenfolge: vierte - dritte - zweite - erste erscheinen.
 
Hallo Midimaster,

danke - das war mir so nicht bewusst. Ich wusste zwar, dass die alte Messagebox abgelöst wurde, habe mir aber bei der Bezeichnung Async nichts gedacht. Das erklärt so einiges.

Ich habe die Box bisher immer genutzt, um meinen Code zu testen. Ich ging davon aus, dass das Programm, so wie in anderen Sprachen, an der stelle Stoppt. Gibt es dazu eine Alternative, oder wie testet ihr eine Routine schrittweise??

Gruß Lothar
 

lerneBasic4Android

Member
Licensed User
Die Frustration von Lothar kann ich gut verstehen. Es gibt zwar eine Dokumentation, aber wenn man auch nur eine simple MsgBox machen will, muss man sich mit asynchronen Programmierung beschäftigen, die in den Tutorials auch nur sehr kompakt erklärt wird. Gerade das Thema ResumableSubs ist ein Dauerbrenner im Forum. Wenn man sich dann durch die Grundlagen der Sprache gekämpft hat und denkt, dass es besser wird, merkt man dass für eine moderne App jede Menge zusätzliche Einträge im Manifest gebraucht werden. Die werden aber auch selten bis nie erklärt, sondern immer nur nach dem Motto "so muss das sein" präsentiert. Daraus kann man nichts lernen. Auch gefeierte Verbesserungen wie die B4XPages delegieren Events irgendwo hin, ohne dass klar ist, was sich hinter der Delegation verbirgt. Leider sind die Zeiten, wo Basic4Android einfach war, längst vorbei. Ich sehe es auch so, dass der Zugang für Neueinsteiger unnötig schwer ist, trotzdem sich im Forum alle große Mühe geben, bei individuellen Problemen zu unterstützen. Aber individuelle Problemlösungen sind eben kein didaktischer Zugang...
Viele Grüße Thomas
 
Hallo LB4A,

ich hatte vor Jahren schon mal ein Programm in B4A geschrieben. Damals gab es noch eine richtige Messagebox. Als ich nach Jahren mal in das Programm reinschaute, hagelte es von Fehlern. Einer davon war die MessageBox. Ich war froh, dass ich die neue fand und problemlos einbinden konnte. Ich habe auch kein Problem damit. Jetzt wo ich weiß, dass sie asyncron funktioniert, kann ich mich darauf einstellen. Das ganze B4A ist für mich reines Hobby und ich habe keinen Druck irgend etwas beenden zu müssen.
Gern hätte ich die Sprache besser gelernt, als nur durch Hinterfragen im Forum oder aus fremden Scripts abzukupfern. Ich finde es wirklich eigenartig, dass es keinerlei deutsche Literatur zu dem Thema gibt. Ich fand einige Tutorials. Die sind aber so alt, dass sie nicht mehr funktionieren. Ich sehe eine menge Bibliotheken ohne zu wissen was die tun.

Gruß Lothar
 

Midimaster

Active Member
Licensed User
Die didaktische Situation von B4X ist eine Katastrophe. Ich habe es neulich schon mal versucht im Forum anzusprechen und um die Einrichtung eines Beginner-Forums gebeten. Doch dort sind alle betriebsblind und sehen nicht, dass dieses Defizit komplett neue Leute davon abhält, mit der Sprache überhaupt zu beginnen. Der Tenor war: "Hier im Forum würde doch bisher jedem geholfen". Dass sich viele vielleicht gar nicht fragen trauen, kann sich dort keiner vorstellen.

Nun vielleicht können wir ja wenigstens die deutsche Seite so gestalten, dass man auf Fragen reagiert und sie nicht bloß kurz beantwortet. Eine Antwort gibt man nicht, damit man zeigen kann, dass man sie selbst kennt. Auch nicht, indem man dem Fragenden antwortet, er hätte bloß ordentlich suchen müssen. Das ist nicht zielführend und hilft dem Fragenden wenig. Die beste Reaktion auf eine Frage wäre immer sich zu Fragen, warum die Frage überhaupt nötig wurde. Eine Frage deutet immer auf ein Defizit in der Anleitung hin. Nehmen wir z..b. die derzeit hunderte von Fragen zum Thema "File.DirInternal und Android 29". Hier ist der Hinweis, dass das so jetzt nicht mehr erlaubt ist doch keine Lösung! Besser wäre ein Tutorial zu schreiben, das für den gesamten Komplex File-Rechte in Zukunft eine klare Handlungsanweisung vorgibt.

Überhaupt diese "Tutorials" hier... Es ist doch kein Tutorial, wenn man ein Code-Snipplet hochlädt und es dann dort nicht auch mit weiterem Text erklärt. Oder wenn man ein ungeschnittes Video einstellt, das zeigt, wie man wild in der IDE agiert. So was will gut aufbereitet sein.

Ebenso sehr bedenklich sind die vielen Abkürzungen oder nicht-Erwähnung der Bibliotheken in der Beiträgen. Da habe ich mich die ersten Wochen echt schwer getan. Sobald man dann zu den "alten Hasen" zählt fällt es einem schon nicht mehr auf. Aber kein Neuling kann nicht CLV xCLV was anfangen. Guter Stil wäre auch hier im Code oben immer die Bibliothek zu erwähnen:

schlechtes Beispiel:
B4X:
Private Sub ResizeItem (Index As Int, Collapse As Boolean)
    Dim item As CLVItem = mCLV.GetRawListItem(Index)
    Dim p As B4XView = item.Panel.GetView(0)
    If p.NumberOfViews = 0 Or (item.Value Is ExpandableItemData) = False Then Return
   ...
besse wäre:
B4X:
Sub Class_Globals
    'some additional variables added to CustomListView:'
    Type ExpandableItemData (CollapsedHeight As Int, ExpandedHeight As Int, Value As Object, Expanded As Boolean)
    Private mCLV As CustomListView ' !!!add this library XCustomListView'

Private Sub ResizeItem (Index As Int, Collapse As Boolean)
    'finds the item at a index position:
    Dim item As CLVItem = mCLV.GetRawListItem(Index)
  
    'finds the "root" panel at this position (container for your content):
    Dim p As B4XView = item.Panel.GetView(0)
    If p.NumberOfViews = 0 Or (item.Value Is ExpandableItemData) = False Then Return
    ...
 

Midimaster

Active Member
Licensed User
Jetzt zu Deiner Frage Gibt es dazu eine Alternative, oder wie testet ihr eine Routine schrittweise??

ich hoffe, du bleibst uns hier im Forum erhalten und du gibst nicht gleich wieder auf. Gerade an Neulingen könnte die Community viele lernen und Defizite erkennen.

also..
Wie teste ich mein Programm?
Das ist eigentlich die zentrale Frage beim Programmieren! Ich würde ja mal behaupten 10 Zeilen Code können 10 Fehler enthalten. Daher mein erster Tipp: nicht den ganzen Code schreiben und dann testen wo es hakt. Besser nach jeder Zeile sofort testen, ob die läuft! Klingt umständlich, dauert aber weniger lang als der andere Weg.

Der optimal Weg herauszufinden ob etwas so ist, wie man es erwartet sind Logs(). Davon gehören meiner Meinung nach hunderte in den Code. Die bleiben da auch bis das Projekt beendet ist. Logs() geben in der IDE Texte aus, während das Programm läuft. Dort kannst du dann sehen, ob alles so ist, wie du es erwsrtet hättest.

Nehmen wir z.b. Deinen code aus #1. Mit logs sieht der so aus:
B4X:
Sub Button1_Click
    Dim Zeit as Long=DateTime.Now
    xui.MsgboxAsync("Erster Eintrag", "Nr 1")
    xui.MsgboxAsync("Zweiter Eintrag", "Nr 2")
    xui.MsgboxAsync("Dritter Eintrag", "Nr 3")
   xui.MsgboxAsync("Vierter Eintrag", "Nr 4")
    log("************************************Button1 FERTIG nach msec=" & (DateTime.Now-Zeit))
End Sub
So würde ich sowas schreiben. Jede SUB bekommt bei mir immer einen Speedtest. In der ersten Zeile wird die Stoppuhr gestartet, in der letzten Zeile wird als Beleg dass die gesamte Funktion durchlaufen ist ein Log() ausgegeben, der dann auch noch die Zeit angibt, die diese SUB benötigt hat.

Schon damit wäre dir aufgefallen, das die SUB fertig ist, bevor du die erste MSG-Box wegklickst. Klappt dann etwas nicht, dann kannst Du weitere LOG()-Zeilen zwischen die Befehle einfügen um den Fehler einzugrenzen.
B4X:
Sub Button1_Click
    Dim Zeit as Long=DateTime.Now
    log("Button1 klickt")
    xui.MsgboxAsync("Erster Eintrag", "Nr 1")
    log("nach nr 1")
    xui.MsgboxAsync("Zweiter Eintrag", "Nr 2")
    log("nach nr 2")
    xui.MsgboxAsync("Dritter Eintrag", "Nr 3")
     log("nach nr 3")
   xui.MsgboxAsync("Vierter Eintrag", "Nr 4")
    log("************************************Button1 FERTIG nach msec=" & (DateTime.Now-Zeit))
End Sub


Das gleiche mal auf deine Foto-Sub übertragen:
B4X:
Sub Foto_oeffnen
    Dim Zeit as Long=DateTime.Now
    log("SUB Foto_oeffnen")
     If File.IsDirectory(Verzeichnis,Dateiliste.get(Bildnummer)) = False Then
         log("ist kein Directory")
       ImageView1.Bitmap = LoadBitmapSample(Verzeichnis,Dateiliste.get(Bildnummer),500,500)
       log("bild geladen" & Dateiliste.get(Bildnummer))
           If File.Exists(File.Dirinternal,Dateiliste.Get(Bildnummer)&".titel") Then
           log("titel datei existiert")
            TitelText.Text = File.ReadString(File.Dirinternal,Dateiliste.Get(Bildnummer)&".titel")
            log("...und geladen")
        Else
            TitelText.Text = "no"
      End If
   End If
   log("************************************Foto_oeffnen FERTIG nach msec=" & (DateTime.Now-Zeit))

End Sub
Dies ist jetzt die "extrem"-Anzahl an logs(). Die hätte ich erst drin, wenn in diesen Zeilen irgendwo der Wurm steckt. Aber damit findest Du die Stelle ab der es schief läuft zu 100%. Später wenn diese Funktion einwandfrei funktioniert, bleiben z.b. nur noch zentrale logs() darin aktiv:
B4X:
Sub Foto_oeffnen
    Dim Zeit as Long=DateTime.Now
    'log("SUB Foto_oeffnen")
     If File.IsDirectory(Verzeichnis,Dateiliste.get(Bildnummer)) = False Then
         'log("ist kein Directory")
       ImageView1.Bitmap = LoadBitmapSample(Verzeichnis,Dateiliste.get(Bildnummer),500,500)
       log("bild geladen")
           If File.Exists(File.Dirinternal,Dateiliste.Get(Bildnummer)&".titel") Then
           'log("titel datei existiert")
            TitelText.Text = File.ReadString(File.Dirinternal,Dateiliste.Get(Bildnummer)&".titel")
            'log("...und geladen")
        Else
            TitelText.Text = "no"
      End If
   End If
   log("************************************Foto_oeffnen FERTIG nach msec=" & (DateTime.Now-Zeit))

End Sub
 
Last edited:
Hallo Midimaster,

vielen Dank für deine Mühe. In der Tat bin ich gestern Abend über Log() gestolpert und wollte mir das heute ansehen. Nun hat sich das, dank deines ausführlichen Berichts erledigt. Genau das habe ich gesucht. Und ich dachte, genau das könne ich mit Der Messagebox ausgeben, was ja durchaus in Anderen Programmen funktioniert. Das Log erinnert mich an Print in Phyton. Dort ist es auch so.

Hier in dem Forum ist mir so viel Positives aufgefallen. Hier wird man als Neuling nicht gleich grundlegend nieder gemacht, nur weil man eine Frage nicht besser stellen kann.
Ich bewege mich in den verschiedensten Foren als Fragender und habe bisher kaum kompetente Antworten erhalten. Vor 20 Jahren habe ich mir Herrn Schubert mal VbFun mit moderiert. Das war am Ende so deprimierend, dass ich es gelassen habe.
In einem führenden Microcontroller-Forum habe ich mal eine 100% funktionierende SMD-Platine Platine mit der Frage: "Warum funktioniert meine Schaltung nicht?", eingestellt. Dort wurde die Schaltung so stark diskutiert, was da alles falsch wäre.. Die sogenannten Profis entpuppten sich schnell als Luschen. Aber das nur so am Rande!

Soweit ich sehe, wird hier jeder Beitrag vor dem veröffentlichen kontrolliert. Das ist sicher der Hauptgrund, dass es hier so sozial zugeht.

Noch eine abschließende Frage: Sollte ich für meine Fragen, welche zwar das gleiche Projekt, aber unterschiedliche Themen betreffen, neue Threads öffnen, oder immer den gleichen verwenden?

Bei ein und dem selben Thread befürchte ich, dass am Ende sich niemand mehr die Mühe macht, den bis zum Ende zu lesen.

Gruß Lothar
 

klaus

Expert
Licensed User
Es ist besser, für jede neue Frage einen neuen Thread zu erstellen.

Zum Testen eines Programms benutze ich viel Breakpoints.
Breakpoints halten das Programm in der Zeile an wo der Breakpoint gesetzt ist.
Die Breakpoints setzt man links am Rand des Editor mit einem Mausklick.
Ein Mausklick auf einen Breakpoint setzt diesen wieder zurück.

1602420035428.png


Und der Breakpoint:

1602420048527.png


Wenn man das Programm startet, hält es in der Breakpoint-Zeile 49 an.

1602420084930.png


Wenn man nun mit der Maus über eine Variable fährt, wird deren Wert angezeigt.

1602420204564.png


Dann kann man, mit diesen Knöpfen
1602420268316.png
, das Programm Schrittweise weiter durchlaufen.
1602420346169.png
Das Programm fortlaufen.
1602420392801.png
Aktuelle Zeile durchführen und in der nächsten Zeile anhalten. Schrittweiser Durchlauf.
1602420450367.png
Wenn in der Zeile, die gelbe, die ausgeführt werden soll, ein Aufruf auf eine SubRoutine steht, wird diese ohne Halt durchgegeführt und das Programm hält in der nächsten Zeile wieder an.
1602420604239.png
Wenn die gelbe Zeile in einer Subtoutine steht, wird der Rest dieser Subroutine durchgeführt und Prgramm hält in der Zeile nach dem Routinenaufruf wieder an.
1602420617715.png
Stoppt das Programm und verlässt des Debugger.
1602420633298.png
Neustart.

Das versteht man besser wenn man es ausprobiert.
 
Hallo Klaus,

das hab ich schon verstanden. :) Im BasCom-Interpreter, im VB6 und VB.NET funktioniert das analog. In B4A hatte ich es noch nicht entdeckt.

Danke für den Tipp.

Gruß Lothar

(Ich glaube, den Einzelschrittmodus gibt es hier nicht, aber ich schaue noch.)
 
Hallo,

ich habe ein Modul main. In diesem Modul sind Globale Prozessvariable deklariert.

B4X:
Sub Process_Globals
    'These global variables will be declared once when the application starts.
    'These variables can be accessed from all modules.
    Public Verzeichnis As String
Ich dachte, ich können nun von allen weiteren Modulen auf diese Variable zugreifen können.

Ich war der Annahme, dass in einem weiteren Modul Log(Verzeichnis)
funktioniert. Muss ich wirklich mit Log(main.Verzeichnis)
auf die Variable zugreifen?
Für mein Verständnis wäre normal, ein Klassenmodul zu erstellen und alle gemeinsam benutzten Variablen dort als Public zu definieren. Sicher ist das hier wieder ganz anders.

Des Weiteren hätte ich vermutet, Routinen, welche ich in mehreren Modulen verwende, ebenfalls in einem Klassenmodul zu erstellen.
Gerade dieser Anfang ist für einen Beginner essenziell. Fängt man hier falsch an und gewöhnt sich einen falschen Stil, welcher zwar funktioniert, aber eben nicht korrekt ist, wird man es später schwer haben, den korrekten Weg zu lernen.

Gruß Lothar
 
Hallo Klaus,
sorry, ich habe genau das gemacht, was ich selber verpöne. Posten ohne nachzudenken. Zwischenzeitlich hatte ich das auch gefunden.
(Passiert nicht noch mal.)

Gruß Lothar

Kannst Du mir zu den global verwendeten Variablen was sagen?
 

Midimaster

Active Member
Licensed User
So ist es! Eine Variable Verzeichnis im Module Main kannst Du in anderen Modulen nur als Main.Verzeichnis erreichen.

Bei normalen Modulen wäre ein direktes Erreichen wie du es erwartest tatsächlich noch denkbar. Ich hatte auch schon Sprachen, wo das möglich war. Dies ist reine Festlegungssache des Erfinders der Sprache.

Bei Klassen ist das aber völlig undenkbar und würde dem Prinzip einer Klasse widersprechen. Schließlich soll man ja in Klassen so schreiben können, das man niemals mit anderen Klassen oder Modulen wegen zufällig Namensgleichheiten Probleme bekommmt. Da werden Variablen von außen immer über eine Kombination aus Klassenname und Variablennamen angesprochen.

Bei B4X ist das sogar noch "strenger". Eine in der Klassen global erstellte Variable lässt sich noch nicht mal über Klasse.Variable ansprechen, sondern die Variable entspricht mehr einem Field und ist nur über Instanz.Variable erreichbar.

Beispiel:
angenommen die Klasse heißt BilderClass und enthält die Variable X, dann geht sowas aus Main nicht:
B4X:
Sub Button_Click
    If BilderClass.X=12 Then
es muss erst eine Instanz der Klasse erstellt worden sein:
B4X:
Sub Process_Globals
    Public MyBild as BilderClass
....  
Sub Button_Click
    If MyBild.X=12 Then
Und hast Du in einem weiteren Module noch eine Instanz von BilderClass erstellt, so sind die beiden X unterschiedlich

B4X:
'Module Daten'
Sub Process_Globals
    Public DatenBild as BilderClass
    DatenBild.X=12


'Module Main:'
Sub Process_Globals
    Public MyBild as BilderClass
....  
Sub Button_Click
    log(MyBild.X)
würde beim Klick auf den Button die Zahl 0 ausgeben
 
Hallo MidiMaster,
danke für deine ausführliche Erklärung.
Ich hatte nicht vermutet, dass es in B4A richtige Klassen gibt! Ich glaube, ich sollte B4A langsam mit anderen Augen sehen.
Normale Routinen, welche ich von mehreren Instanzen aufrufe, lagere ich normaler Weise in anderen Programmen in Modulen aus. Ist das hier auch möglich, oder muss ich dafür stets ein Klassenmodul verwenden?
Noch eine Frage - gibt es in B4A Funktionen?

Danke, Lothar
 
Last edited:

Midimaster

Active Member
Licensed User
Also ich habe auch ein Modul mit dem Namen BAS für so 0-8-15-Standardroutinen, die ich von überall rufen könnte. Das Module nehme ich auch zum nächsten Projekt immer mit. Du musst es nicht als Klassenmodul schreiben. So kannst Du die Routinen von überall aufrufen und auch die GLOBALEN dieses Moduls stehen allem gemeinsam zur Verfügung.

B4X:
'Module BAS'
Sub Process_Globals
    Public StartZeitHeute as LONG
...
Sub SetzeStartZeit
    StartZeitHeute=DateTime.Now


'Module Main:'
Sub ACTIVITY_Start
    BAS.SetzteSartZeit

Sub Button1_Click
    log(BAS.StartzeitHeute)



'Module Xyz:'
Sub CheckeWas
    If DateTime.Now > BAS.Startzeit Then

Frage nach den Funktionen
Die B4X-SUBs sind gewissermaßen Funktionen. Du kannst sie aber immer mit oder ohne Werteübergabe und auch mit oder ohne Rückgabe einsetzen. Also so eine Art Universal-Funktionentyp.

B4X:
'ohne alles'
SUB DruckeDatumHeute()
    log("Datum=" & Date.Date(DateTime.Now)
End Sub

'mit Parameter
Sub LoggeDatumIn_X_Tagen(Tage as int )
    log("Datum=" & Date.Date(DateTime.Now + Tage*24*60*60*1000)
End Sub


'mit Rückgabewert
log("Datum=" & DatumIn_7_Tagen()
...
Sub DatumHeuteIn_7_Tagen() as STRING
    Dim Dann as Long=DateTime.Now
    Dann = Dann + 7*24*60*60*1000
    Dim Datum as String=Date.Date(Dann)
    Return Datum
End Sub


'mit Parameter und Rückgabewert
log("Datum=" & DatumInZukunft(7,6,33))
...
Sub DatumInZukunft(Tage as Int, Stunden as INT, Minuten As Int) as STRING
    Dim Dann as Long=DateTime.Now
    Dann = Dann + Tage*Stunden*Minuten*60*1000
    Dim Datum as String=Date.Date(Dann)
    Return Datum
End Sub
 
Last edited:

klaus

Expert
Licensed User
Noch eine Frage - gibt es in B4A Funktionen?
Jede Subroutine kann Werte zurück geben.

Beispiel:
B4X:
Public Sub Summe (Wert1 As Double, Wert2 As Double) As Double
    Private SummeDerWerte As Double
    SummeDerWerte = Wert1 + Wert2
    Return SummeDerWerte
End Sub
Oder einfacher:
B4X:
Public Sub Summe (Wert1 As Double, Wert2 As Double) As Double
    Return Wert1 + Wert2
End Sub
Am Ende muss man den Variablem Type angeben.
Der Wert wird mit Return zurück gegeben.

Und der Aufruf:
B4X:
TotalWert = Summe(100.34, 234.23)
Oder:
B4X:
TotalWert = Summe(A, B)
Man kann auch Objekte zurück geben.
 
Hallo Klaus,

danke, das ist ja super. OK, ich kenne das als Funktion, aber das ist ja egal, solange es diese Funktion gibt. (Welch ein Wortspiel...)

Ich hänge immer noch an der Erkennung der externen SD-Karte. Mein Problem ist, dass es auf meiner internen SD kein Verzeichnis DCIM/Camera gibt. Ich verwende nun ein Setup um den Pfad zur externen SD einzustellen. Nun wollte ich beim Start prüfen, ob es das Verzeichnis auch wirklich noch gibt.
Die Funktion File.IsDirectory schien mir dazu bestens geeignet. Die Euphorie währte nur kurz. Wieso muss ich Verzeichnis und Datei angeben, wenn ich doch nur die Information brauche, ob es den Pfad und das Verzeichnis überhaupt gibt?

Diese Prüfung hätte ich gleich in anderen Progammierumgebungen in ein globales Modul gepackt.

Jetzt bin ich mir nicht sicher, ob ich dafür extra eine Klasse bemühen muss. Wobei die Übergabe und Prüfung in eine Klasse echt kompliziert ist. Sicher auch hier in B4A.


Sicher habe ich hier wieder X Denkfehler...



Gruß Lothar
 
Top