nach Hause
Forschung
Makros   
NMEA & GPS   
Colbitz
links
Fotos
Konzerte
Spielewiese
Gästebuch
privat

   

...der Ernst des Lebens

Einige kleine Makrobeispiele

Ich arbeite bei den Städtischen Werken in einer Abteilung zur Leitungsdokumentation. Es gibt also einen riesigen homogenen Datenbestand, den es gilt mit MicroStation zu beherrschen. Dazu bastele ich mir mit MicroStation-Basic, VBA und VB 6 kleine Helfer.

Dateien umbenennen VB6 Visual BasicNameMix ist ein VB6-Progamm bei dem mit der FileSystemObject und der File-Klasse gearbeitet wurde. Die Dateien werden in eine Liste geschrieben. Anschließend werden Zufallszahlen in dem vorgegebenem Bereich erzeugt. Dies geschieht so lange, bis eine Zahl gefunden wird, die noch nicht vergeben wurde. Jetzt kann die Datei umbenannt werden.

Loop While Dir
     (Dir1.Path & "\" & NewName) <> ""
Set Dat = FS.GetFile
     (Dir1.Path & "\" & FileList(j))
Dat.Name = NewName
j = j + 1

Txt2html sind meine ersten Gehversuche in .net C#. Das Programm liest eine Textdatei und schreibt eine html-Datei. Dabei werden die Umlaute, einige Sonderzeichen sowie die Zeilenumbrüch durch die entsprechende HTML-Syntax ersetzt. Die Zeichen, die umgesetzt werden, sind in einer ASCII-Datei aufgelistet, die natürlich ergänzt werden kann. Einige Probleme bereitete mir das Einstellen des richtigen Zeichensatztes. Dies geschieht durch einen Parameter beim Erzeugen des Reader-Objektes.
FileStream objTxtFile = new FileStream(strTxtFile, FileMode.Open);
StreamReader objReader = new StreamReader(objTxtFile,
                             System.Text.Encoding.GetEncoding("iso-8859-1"));
Für jede Zeile der Textdatei wird die Datei mit den zu ändernden Zeichen einmal durchlaufen. Dabei wird schrittweise die neue Zeile erzeugt.
while ((lstLine = LstReader.ReadLine()) != null)
   {
   ///Schleife, bis Zeichen in der Zeile nicht mehr vorkommt
    testStr=lstLine.Substring(1,(lstLine.Length)-1);
    newLine=newLine.Replace(lstLine.Substring(0,1),
                            lstLine.Substring(1,(lstLine.Length)-1));
   }
LstReader.Close();
objWriter.WriteLine(newLine + "<br>");
DXF_Text durchsucht eine DXF-Datei auch Teexten und schreibt diese in eine Textdatei. Da ja DXF-Datien auch nur ASCII-Dateien sind, sind solche Auswertungen mit ihnen relativ einfach umzusetzen.
Nach dem Programmstart ist eine DXF-Datei VB6 Visual Basic DXF-Dateien analysieren Texte auslesen auszuwählen, sowie eine TXT-Datei anzugeben. Die Vorgabeverzeichnisse hierfür können in der INI-Datei angegeben werden. Der nächste Punkt in der INI-Datei ist der Masterkey. Er beschreibt den Geometrietyp in der DXF-Datei und muss auf TEXT stehen. Unter DezZeich bzw. TrennZeich werden Dezimal- bzw. das Trennzeichen der Spalten in der Ausgabedatei angegeben. Für die weiteren Zeilen der INI-Datei sind Kenntnisse über den Aufbau von DXF-Dateien nötig. Jede Elementeigenschaft wird in einer DXF-Datei durch eine Schlüsselzahl eingeleitet. In der INI-Datei gibt es unter [Spalten] mehrere Zeilen, z.B. 8|4|Ebene. Der erste wert ist die Schlüsselzahl in der DXF-Datei, der zweite Wert gibt die Spalte in der Ausgabedatei an. Ist er Null, wird der Wert nicht ausgegeben. Der dritte Wert steht für den Spaltennamen im Ergebnis. Die Ausgabedatei kann folgendermaßen aussehen:
Text,RW_Lu,HW_Lu,Ebene,RW_Fa,HW_Fa,Farbe,Index
Autobus,-38.556675,-0.576831,0,,,7,1
Autobus,-25.150845,3.771006,0,,,12,2
Bahnhof,-31.49144,-8.823225,0,,,9,3
Wasserwerk,-43.810311,5.669564,0,,,3,4
Durch das einheitliche Trennzeichen können die Dateien einfach in Excel, Access oder ein GIS importiert werden.
Text        RW_Lu       HW_Lu      Ebene  RW_Fa  HW_Fa  Farbe  Index
Autobus     -38.556675  -0.576831  0                     7     1
Autobus     -25.150845   3.771006  0                    12     2
Bahnhof     -31.49144   -8.823225  0                     9     3
Wasserwerk  -43.810311   5.669564  0                     3     4
In den Spalten RW_Fa und HW_Fa werden Koordinaten angegeben, wenn sich der Fangpunkt vom Fußpunkt unterscheidet. Die Spalte Index beinhaltet einen Zähler und wird automatisch angefügt.

dxfread plaziert Punktnummern, die aus einer DXF-Datei gelesen werden in der geöffneten DGN-Datei. Die Punktnummern werden an einem Sachdateneintrag in den DXF-Daten erkannt. Da sich dieser Eintrag im Elementblock nach den Koordinaten und dem Text befindet, wird ein zwanzigzeiliges Feld erzeugt, in dem jeweils alle nötigen Daten vorhanden sind.
open dxfFile for Input Access Read Shared As #1
do while not eof(1)
  line input #1,kette(20)                   'Zeile zur Liste hinzufügen
  i% = 0
  do while i < 20
    kette(i) = kette(i+1)                   'Liste neu ordnen
    i = i + 1
  loop
  if kette(19)="POINTNUMBER" and kette(17)="AcDbAttribute" then
    mPoint.x = val(kette(7))                'Koordinaten auslesen
    mPoint.y = val(kette(9))                'Koordinaten auslesen
    pktNr    = kette(15)                    'Text auslesen
    MbeSendCommand "PLACE DIALOGTEXT ICON"
    MbeSetAppVariable "", "msToolSettings.placeText.type", 0&
    MbeSendAppMessage "TEXTEDIT", "FirstLine " & pktNr
    MbeSendDataPoint mPoint, 1%             'Text plazieren
  end if
loop
close #1

MicroStation V8 Bemaßung VBA DGN-Dateien Bemassung.mvba ist ein VBA-Programm für MicroStation 2005. Es handelt sich um einen ungebundenen Dialog, der auf Mausklicks reagiert. Als erstes muss eine Basislinie abgesetzt werden. Später werden zu dieser Linie rechtwinklig Maßpunkte abgesetzt.
Das Programm besteht aus zwei Schleifen, die durch jeweils einen Rechtsklick verlassen werden. Durch die Zeicheneinstellung msdDrawingModeTemporary können Bezugslinien temporär dargestellt werden.
Set nLine = CreateLineElement2(Nothing, Point1, Point2)
nLine.Redraw msdDrawingModeTemporary
Die Richtungen und Strecken werden durch algebraische Formeln ermittelt.
'Richtung x1x2
tt = 1 / Sqr((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2))

'Länge P1-Pf
a = Sqr((x3 - x2) * (x3 - x2) + (y3 - y2) * (y3 - y2))
b = ((x1 - x2) * (x3 - x2) + (y1 - y2) * (y3 - y2)) / (a * c)
h = a * Sqr(1 - (b * b))
p = c - b * a

'Fußpunkt P4
Point4.X = x1 + tt * (x2 - x1) * p
Point4.Y = y1 + tt * (y2 - y1) * p
Point4.Z = 0
Abschließend werden die entsprechenden Maßzahlen plaziert.
Set nText = CreateTextElement1(Nothing, x2point(rText, dezTr), Point3, rotMatrixZ(r))
ActiveModelReference.AddElement nText
nText.Redraw

Durch das MicroStation 95 Makro eleproper können Elementeigenschaften von Elementen einer DGN-Datei geändert werden.
filePos = element.fromFile(0)
Do While filePos >= 0 and chkSum > 0
  if element.level>0 and element.color>-1 and element.weight>-1 then

    MbeWriteStatus "props " & cstr(element.properties) & " --> " & cstr(optSum)
    element.properties = optSum

    status = element.rewrite()
    element.display MBE_NormalDraw

  end if
  filePos = element.fromFile (filePos + element.fileSize)
Loop
Die Do-Schleife durchläuft alle Elemente der DGN-Datei. Durch die If-Bedingung wird sichergestellt, dass es sich um ein dargestelltes Element handelt.
Die folgenden Darstellungseigenschaften werden als Summe durch die Eigenschaft properties des Elements eingestellt.


Die Makros delCell und delpoint diehnen zum Bereinigen von DGN-Dateien. Bei delpoint werden alle Elemente der DGN-DAtei durchlaufen. Wird eine Linie (Typ 3) gefunden, wird geteste, ob sie eine mindeslänge hat. Ist dies nicht der Fall, wird sie auf eine seprate Ebene verschoben.
'Einlesen der Endpunktkoordinaten
if element.getPoints (gpoint) = MBE_Success Then 'Test, ob das Element eine Linie ist if ((element.type = 3) and (element.level < 63)) then 'Koordinaten auslesen xx0# = gpoint(0).x xx1# = gpoint(1).x yy0# = gpoint(0).y yy1# = gpoint(1).y 'Test, ob die Länge kleiner als (hier) 1mm ist if (sqr(((xx0-xx1)*(xx0-xx1))+((yy0-yy1)*(yy0-yy1)))<0.001) then 'neue Ebene und Farbe zuweisen element.color = 1 element.level = 4 stat = element.rewrite () end if end if end if

emtykill löscht leere DGN-Dateien. Ich benutzte ein anderes Makro, um eine DGN-Datei in Gauss-Krüger-Index-große Dateien zu zerlegen. Dabei können auch leere Dateien entstehen.
Emtykill öffnet nacheinander die DGN-Dateien eines Verzeichnisses und durchläuft sie. Wird ein grafisches Element gefunden, wird die nächste Datei geöffnet. Wird kein Element gefunden, wird die Datei gelöscht.
sub main
  Dim Element as New MbeElement
  Dim FilePos as Long
  Dim flag    as integer

  dgnDummy$ = MbeDgnInfo.dgnFileName             'Name der geöffneten Datei
  dgnPath$  = FileParse$(dgnDummy,2) & "\"       'Pfad der geöffneten Datei
  dgnfile$  = LCase$(Dir$(dgnPath & "*.dgn"))

  while (dgnfile <> "")
    mbeSendCommand ("NEWFILE " & dgnPath & dgnFile)   'neue DGN öffnen
      flag = 0
      filePos = element.FromFile (0)
      do while filePos >= 0                           'DGN durchsuchen
        if element.level > 0 and element.color > 0 then
          flag = 1
          exit do
        end if
        FilePos = element.FromFile (filePos + Element.FileSize)
      loop
    if flag = 0 then
      mbeSendCommand ("NEWFILE " & dgnDummy)
      kill dgnPath & dgnFile                            'Datei löschen
    end if
    dgnFile$ = LCase$(Dir$())                  'nächsten Dateinamen lesen
  wend
end sub
Durchsucht wird das Verzeichnis, in dem sich die geöffnete DGN-Datei befindet. Außerdem sollte die geöffnete Datei nicht leer und nicht zu groß sein, da sie, wenn einen andere Datei gelöscht wird, zwischenzeitig geöffnet wird.


MicroStation V8 VBA Visual Basic Texte ersetztenDie beiden Makros text2txt und textchange zeigen Zugriffsmöglichkeiten auf Texte in DGN-Dateien. Das Makro text2txt schreibt Texte und die dazugehörigen Koordinaten aus einer MicroStation-Datei in eine Textdatei. Es wird benutzt, um in ArcView Punktobjekte zu erhalten, bei denen der Text ein Attribut ist. In diesem Beispiel werden alle Texte berücksichtigt, die einen definierten Teiltext enthalten, dieser Text (fText$) muss im Quelltext eingetragen werden. Es können aber auch ein Filter verwendet werden, die nach den grafischen Ausprägungen selektieren. Zentraler Bestandteil des Makros ist wieder eine DO-Schleife, in der alle Elemente der DGN-Datei durchlaufen werden. Anschließend werden über folgende Schleife Textknoten (mehrzeilige Texte) in einfache Texte umgeformt:
do
  status = element.getString(OrgText)
  EleText = EleText & OrgText
  OrgText = ""
  status = element.nextComponent
loop while status = MBE_Success
Die einzelnen Komponenten des Textknotens werden nacheinander gelesen und zu einem neuen einfachen Text zusammengesetzt.
Anschließend wird der Teiltext kontrolliert (instr gibt die Position im Text an) und die Textkoordinaten ausgelesen.
xx% = Instr(EleText,fText)        'Test, ob Teiltext enthalten ist
'xx% = 1                          'zum Auslesen aller Texte auskommentieren

element.getOrigin(origin)         'Koordinaten an die Variable origin übergeben
Das Makro textchange ersetzt bestimmte Texte, durch andere Texte. Dabei werden keine Textknoten verarbeitet. Diese Funktion ist bereits unter dem Punkt Bearbeiten - Suchen/Ersetzten vorhanden. Das Makro durchsucht aber alle Dateien in einem ausgewähltem Verzeichnis. Zum Abfragen der Texte wird mit einem bunutzerdefinierten Dialog gearbeitet, dessen Layout in der ba-Datei gespeichert ist. Er hat den Index 1 und wird mit
status = mbeOpenModalDialog (1)
aufgerufen. Wird der Dialog abgebrochen, wird das Makro durch
if status <> MBE_BUTTON_OK then exit sub
beendet. Nach der Eingabe der Quell- und Zieltexte muss das zu bearbeitende Verzeichnis ausgewählt werden. Durch eine while-Schleife werden die DGN-Dateien nacheinander geöffnet.
DesignFile$ = Dir$(Directory$ & "*.dgn")
While DesignFile <> ""
  MbeSendCommand "NEWFILE " & Directory & DesignFile     'Datei öffnen
  ....
  DesignFile = Dir$
Wend
Durch die drei Zeilen
MbeSendCommand "FIT VIEW EXTENDED 1"
MbeSetAppVariable "VIEWCTRL", "dialogInfo.p.zoomRatio", 2#
MbeSendCommand "ZOOM OUT EXTENDED 1"
wird in Ansicht eins auf den gesamten Inhalt der DGN-Datei gezoomt. Anschließend werden wieder die einzelnen Elemente der DGN-Datei durchlaufen. Für jedes Textelement (Typ 17) werden folgende Zeilen ausgeführt:
if element.Type = 17 then
  status = element.getString(DgnText)                    'Zeichenfolge auslesen
  if DGNText = OrgText then                              'Zeichenfolge vergleichen
    if element.setString (NewText) = MBE_Success then    'neue Folge zuweisen
      status = element.rewrite ()                        'Änderungen übernehmen
    else
      MbeWriteError ("Zeichenfolge kann nicht geändert werden")
    end if
  end if
end if
Abschließend wird zum nächsten Element gewechselt. Diese beiden Makros wurden unter MicroStation 95 geschrieben.


Zur Zeit setzte ich mich besonders mit html, ... und .net C# auseinander. Demnächst kommt noch ArcGis mit Phyton.


update 05.11.2023 • info@fraleco.de • unter Anleitung von selfhtml • getestet mit Mozilla Firefox 2.0