Alle Beiträge von Björn Karpenstein

Diplom Informatiker, Programmierer, Musikbegeisterter

VBA und SAP: Funktionsbausteine aufrufen

Aufgabenstellung

Die Aufgabenstellung sowie der Ansatz ist identisch mit diesem Artikel (Bitte zuerst lesen).

Prämissen / Vorraussetzungen

Die Datei librfc32.dll muss im VBA Editor eingebunden werden (sie ist nach der Installation der SAPGUI verfügbar).

Lösung

Aufbau der Verbindung

Public Function SAP_Logon(username As String, password As String) As Boolean
'*************************************************
'  ANMELDUNG AN SAP
'  ACHTUNG: USER MUSS BERECHTIGUNGEN HABEN!!!!
'*************************************************

    Set FunctionCtrl = CreateObject("SAP.Functions")
    'Objekt für die SAP Verbindung

    Set SapConnection = FunctionCtrl.Connection
   
    SapConnection.Client = "100"
    SapConnection.User = username
    SapConnection.Language = "DE"
    SapConnection.password = password
    
     SapConnection.hostname = "rechnername.firma.com" 'nicht das kuerzel wie DE9
    
    SapConnection.systemnumber = "0"

    If Not SapConnection.Logon(0, True) Then 'True silent - false offen
        MsgBox "Logon failed!!!", vbCritical
        CMS_Logon = False
    Else
        CMS_Logon = True
    End If
End Function

Abmelden

Public Function SAP_Logoff() As Boolean
    SapConnection.LogOff
End Function

Funktionbaustein befüllen und aufrufen

Public Function SAP_Create_Request() As Long
'******************************************************
'  Request erzeugen
'  Strukturen füllen und übergeben, dann Log ausgeben
'******************************************************

On Error GoTo ErrorMSG

    Dim FunctionModule As Object
    Dim e_EXPORTSTRUKTUR As Object
    Dim T_TABELLENSTRUKTUR As Object
    
    Dim te_messtab As Object
    
    Dim lCnt As Long

'   Assign Function Module
    Set FunctionModule = FunctionCtrl.Add("Z_FUBA")
    
'   Set export Variables
    Set e_EXPORTSTRUKTUR = FunctionModule.Exports("P_STRUKTURPARAMETER")

' Set structrue fields in export parameter
    e_EXPORTSTRUKTUR ("ZEXPORTPARAM1") = "BLA"
    e_EXPORTSTRUKTUR ("ZEXPORTPARAM1") = "BLA2"

    Set T_TABELLENSTRUKTUR  = FunctionModule.Tables("T_ZMMMATANF8")
    T_TABELLENSTRUKTUR.appendRow
    T_TABELLENSTRUKTUR(1, "SPALTE1") = 1
    T_TABELLENSTRUKTUR(1, "SPALTE2") = 2

    T_TABELLENSTRUKTUR.appendRow
    T_TABELLENSTRUKTUR(2, "SPALTE1") = 3
    T_TABELLENSTRUKTUR(2, "SPALTE2") = 4

'   Call Function Aufruf
    If FunctionModule.Call = True Then
        Set te_messtab = FunctionModule.Tables("TE_MESSTAB")
        ' Meldungen ausgeben:
        
        Dim intRow As Integer
        For intRow = 1 To te_messtab.RowCount
            If te_messtab(intRow, "ARBGB") = "ZMM0001" And _
                te_messtab(intRow, "MSGNR") = "003" Then

                ' ANForderung wurde erstellt.
                CMS_Create_Request = Val(te_messtab(intRow, "MSGV1"))
            End If
            Debug.Print te_messtab(intRow, "ARBGB")
            Debug.Print te_messtab(intRow, "MSGNR")
            Debug.Print te_messtab(intRow, "NATXT_DE")
            sMSGTXT = te_messtab(intRow, "NATXT_DE")
            Debug.Print te_messtab(intRow, "FLDNAME")
            Debug.Print te_messtab(intRow, "MSGV1")
            Debug.Print te_messtab(intRow, "MSGV2")
            Debug.Print te_messtab(intRow, "MSGV3")
            Debug.Print te_messtab(intRow, "MSGV4")
            Debug.Print "----------------------------------"
        Next
    Else
        CMS_Create_Request = 0
         MsgBox "Error creating the CMS Request." & vbNewLine & _
                "See Log for details", vbCritical
    End If
ErrorMSG:
  
End Function

Die Testfunktion

Public Sub Start()
'*************************************************
'  TESTUMGEBUNG
'*************************************************
    Dim RequestNo As Long
    Dim username As String
    Dim password As String
    
    username = "BJOERN"
    password = "ICHBINDERBESTE"
        
    Call CMS_Logon(username, password)
    RequestNo = SAP_Create_Request   
    Call CMS_Logoff
End Sub

Arduino Uno Lichterkette mit Dämmerungssensor

Aufgabenstellung

Für die Ansteuerung externer Elektronikgeräte wird eine programmierbare Lösung gesucht, die auch kabellos per Batterie betrieben werden kann und Eingabewerte (z.B. Sensorwerte) einlesen kann.

Ansatz

Die Verwendung eines Mikrocontrollers ist notwendig. Mikrocontroller sind sehr stromsparende, programmierbare und mobile Systeme, die nur das nötigste an Anschlüssen für das Aufbauen komplexer Elektronikschaltungen besitzen.

Lösung

Auf die Empfehlung eines Elektronikfreaks habe ich mir das Arduino Uno zugelegt. Hierbei handelt es sich um ein programmierbares Board mit 1KByte Flash-Speicher und einer ATMega Prozessor.

Beurteilung

Da man auf einer sehr niedrigen Ebene mit Bauteilen arbeitet, würde sich ein Elektrotechnikgrundkurs anbieten.

Adobe InDesign: Drucken von DIN A5 Faltheftchen

Aufgabenstellung

Es soll ein Din A5 Faltheftchen mit Adobe InDesign erstellt werden, welches auf dem Heimdrucker ausgedruckt werden kann.

Voreinstellungen

Zunächst wird ein Dokument mit den Maßen für Din A5 (Document Setup) erstellt:

Problem 1

Als erstes muss klar sein, das ein A5 Heftchen aus gefalteten DIN A4 Blättern besteht. Jedes DIN A4 Blatt wird beidseitig bedruckt und bietet Platz für 4 DIN A5 Seiten.

Lösung 1

Also sollte die Seitenanzahl durch 4 teilbar sein, bevor man druckt, damit man nicht anfangen muss zu kleben und zu basteln. Ein Dokument hat idealerweise eine Seitenzahl von n=4*x (x:DIN A4 Blätter). Unbenutzte Seiten können mit Bildchen und anderen Platzauffüllern besetzt werden.

Problem 2

Viele Drucker haben keine Duplex-Einheit für den beidseitigen Druck.

Lösung 2

Hierfür muss eine Treibereinstellung des Druckertreibers genutzt werden (beidseitiger Druck auf manuell), der zunächst alle ungeraden Seiten druckt, und danach auffordert den Papierstapel erneut wie gedruckt (mit der Schrift nach oben) einzulegen. Das Betätigen des Weiter-Buttons druckt anschließend die geraden Seiten aus.
Hierfür empfehle ich die normale Print-Option (nicht Print Booklet) zu verwenden. Es muss lediglich auf die Seitenzahl (Problem 1) geachtet werden und leere Seiten mit Platzhaltern aufgefüllt werden.

Beispiel-Dokument

Folgendes Kirchenheft wurde mit 8 Seiten mit InDesign CS4 erstellt und als DIN A5-Booklet über die normale Print-Option gedruckt:
Beispiel Dokument

HTML5: Mit Canvas malen

Aufgabenstellung

In einem HTML 5 Canvas soll über JavaScript-Events die Mausposition ausgelesen, und an dieser gemalt werden.

Ansatz

Verwendung der Events onmousedown, onmouseup, onmousemove des Canvas-Elements. Nutzung der clientX- und clientY-Eigenschaft

Prämissen / Vorraussetzungen

Es wird ein aktueller Browser verwendet, der das HTML 5 Canvas-Element unterstützt.

Lösung

<html>
<head>
<script>
	function draw() {
		var canvas = document.getElementById("canvas");
		var ctx = canvas.getContext("2d");
		ctx.fillStyle = "black";
		ctx.beginPath();
		var x;
		var y;
		canvas.onmousedown = function(e) {
			x = e.clientX;
			y = e.clientY;
			ctx.moveTo(x, y);
		}
		canvas.onmouseup = function(e) {
			x = null;
			y = null;
		}
		canvas.onmousemove = function(e) {
			if (x == null || y == null) {
				return;
			}
			x = e.clientX;
			y = e.clientY;
			x -= canvas.offsetLeft;
			y -= canvas.offsetTop;
			ctx.lineTo(x, y);
			ctx.stroke();
			ctx.moveTo(x, y);
		}
	};
</script>
</head>
<body onload="draw();">
	<canvas id="canvas" width="300" height="300"
		style="border: 1px solid black;"></canvas>
</body>
</html>

MS SQL Server: DROP TABLE wenn die Tabelle nicht existiert

Aufgabenstellung

Eine Tabelle soll gelöscht werden wenn sie existiert.

Problem

Nutzt man in einem TSQL-Skript den DROP Table Befehl (z.B. in einer Stored Procedure) erhält man eine Fehlermeldung, das die zu löschende Tabelle nicht existiert. In einigen Fällen führt dies zum Abbruch des Skriptes.

Ansatz

Über das META-Schema vom MS SQL Server lässt sich erfragen, ob eine Tabelle existiert.

Lösung

IF EXISTS(SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'users') 
DROP TABLE users;

MS SQL Server und ACCESS: Führende Nullen in numerischem String abschneiden

Aufgabenstellung

In einer Spalte mit Materialnummer/Artikelnummern werden bei allen numerischen Materialnummern die Nullen entfernt, alphanumerische Materialnummern bleiben unberührt. Soll auch bei den alphanumerischen Materialnummern die führenden Nullen entfernt werden, verweise ich auf den Artikel in der Rubrik „MS SQL Server: Führende Nullen bei alphanumerischem String“.

Ansatz

Über das Case Statement wird gefragt ob der Artikel numerisch ist. Ist er numerisch, wird über die Konvertierung in einen Integer (und anschließendes Zurückkonvertieren in VARCHAR) die führenden Nullen entfernen.

Lösung

Microsoft SQL Server:

UPDATE tabelle SET material=
CASE WHEN isnumeric(material)=1 
        THEN convert(VARCHAR, convert(INTEGER, material))
        ELSE convert(VARCHAR, material)
END 

Microsoft Access:

   UPDATE articletexts SET material=
   IIF(IsNumeric(material), 
   REPLACE(LTRIM(REPLACE(material,'0',' '))
   ,' ','0'), material) 

Adobe Flex 3: Charaktere aus Flash Professional CS4 exportieren und einbinden

Aufgabenstellung

Es wird ein Grundgerüst für eine Flex-Anwendung erstellt, auf dessen Basis Animationen und Charaktere, die aus Flash CS4 exportiert worden, gesteuert werden können.

Intention

Da Adobe Flex als Entwicklungsumgebung für Programmierungen wesentlich mehr Features bietet als Flash (Context-Hilfe, Syntax-Highlighting, Design-Time-Prüfungen), wird versucht die Vorteile von Beiden Umgebungen zu nutzen und ein Flashspiel mit Flex, dessen Focus auf der Entwicklung mit Eclipse liegt, zu implementieren.

Ziel

Ziel ist das Auffinden von Bests Practices bei der Spieleentwicklung mit Flash/Flex.

Vorgehensweise 1

Erstellen von Animationen

Es werden 2 Loop-fähige Animationen erstellt, die nachher als Symbol konvertiert werden
Hier:
– Moving Landscape
– Character

Export aus Flash / Import in Flex

  • Flash schließen
  • Adobe Account anlegen
  • Flex Component Kit bei Adobe runterladen
  • Flex Component Kit mit Adobe Extension Installer installieren
  • Nur bei Problem mit Deutschen Versionen: Das in C:\User … … AppData … Adobe Flash CS4 … !!!DE!!! … Configuration-Verzeichnis in das auf der gleichen Ebene befindliche !!!EN!!! Verzeichnis kopieren
  • Flash neu starten
  • Die auf der Stage befindlichen Ebenen markieren
  • Menülieste: Modify -> Convert to Symbol
  • In Library (STRG+L) Symbol anklicken
  • Neues Menü: Command – Convert to Flex Component aufrufen
  • File->Publish aufrufen
  • In der Library auf dem neuen Flex Symbol -> Rechte Maustaste -> Convert to SWC (vorher auch unter Properties die Classnamen angeben)
  • In das Flex Projekt (lib-Verzeichnis) kopieren
  • Die Komponente steht in MXML zur Verfügung, wenn man den unter Properties angegebenen Classnamen aufruft

Versuch die Komponenten über Flex zu steuern

<?xml version="1.0" encoding="utf-8"?>
<mx:Application horizontalScrollPolicy="off" verticalScrollPolicy="off" 
          creationComplete="{onCreationComplete()}" 
         xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" xmlns:local="*" >
  <mx:Script>
  	<!&#91;CDATA&#91;
  		public function onCreationComplete():void
  		{
  			test3.scaleX=-1;
  		}
  	&#93;&#93;>
  </mx:Script>
 <local:landscape x="1400" y="600" height="600">
 </local:landscape>
 <local:MeinTest id="test3" height="300"  y="370" x="200" >
 </local:MeinTest>	
 <mx:ApplicationControlBar x="0" y="0" width="100%" height="50">
  <mx:Button click="{test3.gotoAndStop(0)}" label="Stop"/>
  <mx:Button click="{test3.gotoAndPlay(0)}" label="Start"/>
  <mx:Button click="{test3.scaleY*=-1;test3.scaleX*=-1}" label="Drehen"/>
 </mx:ApplicationControlBar>
</mx:Application>

Ergebnis

Problem

Die UIMovieClips lassen sich zwar rotieren, aber nicht per scaleX um die eigene Achse drehen.

Abhilfe

Wird noch gesucht

Adobe Flex 3: Composite Pattern für Charakter-Animation mit inverser Kinematik

Aufgabenstellung

Es wird eine Flex-Anwendung entwickelt, die das Grundgerüst für ein 360 Grad Flex-Spiel mit einer Schlange erstellt.

Ansatz

Unter der Verwendung des Composite-Patterns werden die Teile der Schlange zusammengesetzt. Die Teile interagieren über „inverse Kinematik“ miteinander, d.h. jedes Teil ist Autonom, wird aber von seinem Verbindungsteil gezogen.

Die Schlange verfügt über die Eigenschaften:
– gleichmäßig beschleunigte Bewegung (Up-Taste am Keyboard)
– gleichmäßig verzögerte Bewegung (Up-Taste loslassen)
– Rückimpuls (Kollision mit Button)
– Lenkung in der Beschleunigung (Left- und Right-Button)
– Jedes vordere Verbindungsstütz zur Schlange bestimmt die Position des hinteren (inverse Kinematik)

Der Code ist minimal, die Main-Datei besteht lediglich aus der Schlange selbst und der Angabe, welches UI-Objekt eine Barriere (hier „Der böse Button“) sein soll. Diese Barriere verfügt über die Eigenschaften des Back-Impulses bei einer Kollision in der Beschleunigung.

Main-Code:

<?xml version="1.0" encoding="utf-8"?>
<mx:Application backgroundColor="#ffffff" xmlns:mx="http://www.adobe.com/2006/mxml" 
                         layout="absolute" xmlns:snake="org.actionscript.snake.*">
  <snake:Snake barrier="{boeserButton}" height="100" width="100" snakelength="100" />
  <mx:Button x="10" y="256" id="boeserButton" width="400" label="Der böse Button" />
</mx:Application>

Lösung

In neuem Browser öffnen (bitte 1x anklicken und dann Pfeiltasten benutzen)

Code

Der Code wurde im Flex-Builder 3 entwickelt und ist als Flex 3-Projekt gezippt.
Adobe Flex 3 Projekt downloaden

C# und OleDBParameter: Reihenfolge von Parametern

Problem

(Ein kleiner Schmunzelartikel)… Da sitzt man seit Stunden vor einem normal aufgebaut SQL Statement mit einem OleDbCommand… es ist alles so wie bei einen SQLCommand…. und das Statement tut nichts… gar nichts…

Lösung

Die Reihenfolge von OleDBParametern ist NICHT assoziativ wie durch die Namensgebung vermutet… es spielt gar keine Rolle ob ein Statement mit einem ? oder einem @parametername versehen wird. Die Reihenfolge muss immer stimmen, wenn man mit

comm.Parameters.AddWithValue("parametername", variable)