MapInfo-Tips
- MapInfo’s internal coordinate precision
- MIDLOIC.DLL-Problem
- Koordinatensysteme
- Abschneiden von Leerzeichen
- Änderung auf Groß-/Kleinschreibung
- Bestimmung sich selbst schneidender Objekte
- Custom Affine projection
SQL-Tips
- Abschneiden von Leerzeichen
- Änderung auf Groß-/Kleinschreibung
- Selektion komplexer Objekte
- Auswahl Datensätzen mit Werten aus einer anderen Relation
- Geographische Ausdehnung und Größe von Objekten bestimmen
- RowId anzeigen
- Auswahl von Punkten außerhalb einer Fläche
- Auswahl von angrenzenden Flächen zu einer selektierten Fläche
- Bestimmung sich selbst schneidender Objekte
- Exakte Systemzeit
MapBasic-Tips
- Freier Festplattenspeicher – Determine free disk space
- MapInfo-Fenster anordnen
- Date Label Formatting
- Dateien in Verzeichnis
- Fensterposition bestimmen
- Setzen von Schriftarten
- Überspringen gelöschter Records
- Koordinatensysteme
- Setzen des MapInfo-Applikationstitels
- Universal Translator API
- Information about opened tables and columns in tables
MapInfo-Tips
MapInfo’s internal coordinate precision
Source: Derek_Snyder@mapinfo.com
MapInfo coordinate data is stored as scaled integers, regardless off the coordinate system used. The integers are scaled based on the bounds of the coordinate system used. You can think of the coordinate system as a big sheat of grid paper, where the only legal values are at the grid intersection points. The reasons for using this scheme are historical – partly related to older PC’s not always having FPU’s, thus making floating point arithmetic very slow, and partly due to saving disk space (a 4 byte integer compared to a 8 byte double precision floating point number). Changing newer TAB files to use floating point number has implications, such as backward compatibility, that I won’t get into here.
In this example, you start out with a line segment and get the coordinates of the endpoints of the line as floating point numbers. You then extend the line using floating point arithmetic, and feed the numbers back into MapInfo. MapInfo will convert them to the integer grid, which may move the point slightly as viewed as a floating point number. You may be able to see this if you re-extract the coordinates of your „extended“ line. What you would see is that the lines appear to line up from a distance, but as you zoom in, you will likely see the small variation in the line that you have created.
There are a couple of things that you can do to help this problem. One would be to make the new line that you create be at least a 3 node polyline – containing the first 2 nodes of the original line, plus the new extended point. Then this new polyline will line up exactly with the old line, although it will not be quite straight – it should appear to be straight, but it will be ever so slightly non-linear.
The other thing you can do is to increase the resolution of the data. This can be done by tightening the bounds of the data – remember, the integer cooordinates are scaled numbers based on the bounds. This can be accomplished using the CoordSysBounds.MBX tool that comes with MI Pro. Making the bounds smaller will essentially produce a finer grid. This will not totally eliminate the problem, as the floating point coordinates will still snap to a grip coordinate, but it can substantially reduce the problem.
I would warn against making the bounds too tight. Once the bounds are set, nothing can exist or be added to the table that is outside that bounds. So, when adjusting bounds, always ensure that there is sufficient room for any expansion in the table.
MIDLOIC.DLL-Problem
The error message for MIDLOCI.dll can occur because the Oracle8i driver was selected to be installed as part of the RDBMS\ODBC portion
of MapInfo and the Oracle8i client software is probably not installed on your system which this dll looks for on startup if present.
If you do not have the Oracle8i client installed, remove the midloci.dll from your MapInfo program folder and the error message will no longer occur.
Koordinatensysteme
Die Koordinatensysteme bzw. Kartenprojektionen führen bei der Nutzung von MapInfo Professional sowie bei der Entwicklung von
MapBasic-Applikationen immer wieder zu Überraschungen. Tatsächlich gibt es vier unabhängige Koordinatensysteme in MapInfo/MapBasic.
- Jede kartierbare Relation besitzt eine eigene Kartenprojektion, die bei der Definition der Relation oder bei Datei > Speichern unter festgelegt wird.
- Jedes Kartenfenster besitzt eine eigene Kartenprojektion, die durch das Anzeigen der ersten Relation dieses Fensters festgelegt wird.
- Jedes MapBasic-Programm besitzt eine eigene Kartenprojektion (standardmäßig geographische Koordinaten oder über set coordsys … festgelegt..
- Jeder interaktive Anwender besitzt eine eigene Kartenprojektion, über Run Command „Set Coordsys …“ festgelegt.
Der Unterschied zwischen 3 und 4 wird dabei häufig übersehen.
Abschneiden von Leerzeichen
Um vorlaufende oder anhängende Leerzeichen zu entfernen, können Sie die Funktionen LTrim$() und RTrim$() verwenden:
Update {table} set {Column}=Ltrim$(Rtrim$({Column}))
Änderung auf Groß-/Kleinschreibung
Um den Wert eines Textattribute auf Großbuchstaben zu ändern, können Sie die Funktion UCase$() verwenden:
Formulieren dazu Sie dazu die folgende SQL-Anweisung (bzw. nutzen Sie Relation > Spalte aktualisieren):
Update {table} set {Column}=UCase$({Column})
Zur Änderung in Kleinbuchstaben verwenden Sie die Funktion LCase$(), für Groß-/Kleinschreibung Proper$().
Bestimmung sich selbst schneidender Objekte
Der Umring eines flächenhaften Objekts kann sich, z.B. infolge unsauberer Datenerfassung, selbst überschneiden. Um solche Objekte zu suchen,
wählen Sie den Menüpunkt Abfrage / SQL-Auswahl und formulieren Sie folgende Bedingung:
select objectinfo(intersectnodes(obj,obj, 1),20) from {table} into result Browse * From result
Dabei ist {table} der Name Ihrer Tabelle. Die Anzahl der Schnittpunkte werden Ihnen angezeigt.
In einem MapBasic-Program lautet der symbolische Name für den letzten Parameter INCL_CROSSINGS!
Custom Affine projection
Source: Neil Moseley Geodata Computing Services, mailto:mose@iinet.net.au http://members.iinet.net.au/~mose/
It is just a case of defining a custom Affine projection to represent your non-earth data. Essentially this describes transformation parameters to get from real earth coordinates to your local coordinate system. Your non-earth coordinate values will be the same, but everything will now also plot in the correct position on the earths surface and can be overlayed with real earth data.
What you need are the Affine parameters a,b,c,d,e,f for:
X‘ = Ax+By+C Y‘ = Dx+Ey+F
or
X‘ = Cos(theta)*x+Sin(Theta)*y+c Y‘ = -Sin(theta)*x+Cos(Theta)*y+f
where theta is the angle of the coordinate system, C is the offset in the x direction and F the offset in the Y direction.
These can be used in a custom projection (in this case based on Australian Map Grid 50, datum AGD84):
"My Affine Projection", 3008, 13, 7, 117, 0, 0.9996, 500000, 10000000, 7, A, B, C, D, E, F, Bounds Clause
Or with real numbers:
"My Affine Projection", 3008, 13, 7, 117, 0, 0.9996, 500000, 10000000, 7, 0.780100691704, 0.619057142912, -5308307.365, -0.619057142912, 0.780100691704, -5516110.998, 0, 0, 500000, 500000
To help with the parameters my Affine calculator should be of use. It is an ActiveX component, so you will need to use MS Internet Explorer and also set your security settings to low: http://members.iinet.net.au/~mose/prod03.html
>SQL-Tips
Abschneiden von Leerzeichen
Um vorlaufende oder anhängende Leerzeichen zu entfernen, können Sie die Funktionen LTrim$() und RTrim$() verwenden:
Update {table} set {Column}=Ltrim$(Rtrim$({Column}))
Änderung auf Groß-/Kleinschreibung
Um den Wert eines Textattribute auf Großbuchstaben zu ändern, können Sie die Funktion UCase$() verwenden:
Formulieren dazu Sie dazu die folgende SQL-Anweisung (bzw. nutzen Sie Relation > Spalte aktualisieren):
Update {table} set {Column}=UCase$({Column})
Zur Änderung in Kleinbuchstaben verwenden Sie die Funktion LCase$(), für Groß-/Kleinschreibung Proper$().
Selektion komplexer Objekte
Komplexe Objekte können in MapInfo Professional aus mehreren Polylinien oder Bereichen zusammengesetzt sein. Um solche komplexe Objekte zu suchen,
wählen Sie den Menüpunkt Abfrage / SQL-Auswahl und formulieren Sie folgende Bedingung:
Select * From {table} Val(Str$(ObjectInfo(Obj,21))>1
Dabei ist {table} der Name Ihrer Tabelle.
Auswahl Datensätzen mit Werten aus einer anderen Relation
Für die Auswahl von Datensätze einer Relation {SecondTable}, deren Attributwert {ColumnB} in einer anderen Relation in der
Spalte {ColumnA} enthalten ist, formulieren Sie folgende SQL-Anweisung:
Select * From {SecondTable} Where {ColumnB} = Any (Select {ColumnA} From {FirstTable})
Geographische Ausdehnung und Größe von Objekten bestimmen
Um die geographische Ausdehnung von Objekten zu bestimmen, sollten Sie zunächst das interne Koordinatensystem auf die
Kartenprojektion der auszuwertenden Tabelle setzen, sonst erhalten Sie in den meisten Fällen geographische Koordinaten (Länge und Breite) geliefert.
set coordsys table {Table}
Dabei ist {Table} der Name Ihrer Tabelle. Formulieren Sie nun die folgende SQL-Anweisung (im MapBasic-Fenster):
Select ObjectGeography(Object,3)"MaxX", ObjectGeography(Object,1)"MinX",ObjectGeography(Object,4)"MaxY", ObjectGeography(Object, 2)"MinY" From {Table}
Wenn es sich um linienförmige Objekte handelt, können Sie über
Select ObjectLen(Object, "m")"Länge" From {Table}
die Länge dieser Objekte bestimmen. Wenn es sich um flächförmige Objekte handelt, können Sie über
Select Area(Object, "sq m")"Fläche" From {Table}
die Fläche dieser Objekte in Quadratmeter bestimmen. Bevorzugen Sie als Einheit Quadratkilometer, ersetzen Sie sq m durch sq km.
RowId anzeigen
To get a table to display the RowID as a value in a browser (numbering each record 1 to N) you can use the following command:
Add Column YourTable (RID Integer) From YourTable Set to RowID
Quelle: Dmitry Bogdanov
Auswahl von Punkten außerhalb einer Fläche
Für die Auswahl von Punkten außerhalb einer Fläche, formulieren Sie folgende SQL-Anweisung:
Select * From {Points Table} Where Not Obj Within Any (Select Obj From {Region Table})
Auswahl von angrenzenden Flächen zu einer selektierten Fläche
Für die Auswahl von Flächen einer Relation, die an eine selektierte Fläche angrenze, formulieren Sie folgende SQL-Anweisung:
Select * From {region table} where Obj Intersects Any (Select Obj From Selection)
Bestimmung sich selbst schneidender Objekte
Der Umring eines flächenhaften Objekts kann sich, z.B. infolge unsauberer Datenerfassung, selbst überschneiden. Um solche Objekte zu suchen,
wählen Sie den Menüpunkt Abfrage / SQL-Auswahl und formulieren Sie folgende Bedingung:
select objectinfo(intersectnodes(obj,obj, 1),20) from {table} into result Browse * From result
Dabei ist {table} der Name Ihrer Tabelle. Die Anzahl der Schnittpunkte werden Ihnen angezeigt.
In einem MapBasic-Program lautet der symbolische Name für den letzten Parameter INCL_CROSSINGS!
Exakte Systemzeit
Um eine genauere Zeitangabe als bei der MapBasic-Funktion Time zu erhalten, können Sie eine Betriebssystem-Funktion des Windows-API nutzen, wie es der folgende Code zeigt:
Type SYSTEMTIME wYear As SmallInt wMonth As SmallInt wDayOfWeek As SmallInt wDay As SmallInt wHour As SmallInt wMinute As SmallInt wSecond As SmallInt wMilliseconds As SmallInt End Type Declare Sub GetSystemTime Lib "kernel32" Alias "GetSystemTime" (lpSystemTime As SYSTEMTIME) Declare Sub Main Sub Main Dim myTime as SYSTEMTIME Call GetSystemTime(myTime) Print chr$(12) Print "Time" Print myTime.wYear Print myTime.wMonth Print myTime.wDay Print myTime.wHour Print myTime.wMinute Print myTime.wSecond Print myTime.wMilliseconds End Sub
MapBasic-Tips
MapBasic stellt Ihnen eine Entwicklungsumgebung zur Verfügung, die Ihnen die Erweiterung von MapInfo erlaubt. Dadurch können Sie mit einer leistungsfähigen, BASIC- ähnlichen Programmiersprache Funktionen hinzufügen und auch häufig wiederkehrende Aufgaben automatisieren und diese komfortabel in die Benutzeroberfläche der MapInfo-Anwendung integrieren.
Freier Festplattenspeicher – Determine free disk space
Here is some code that will return (I think it does) the total number of free bytes on a drive. You need to call the …Ex function
and do some juggling to recompose the value (it might be > than integer maximum). I would love to get some improvements on this if it is necessary.
One interesting question: the returned value is quite different from what „properties“ of C:\ (windows explorer) gives.
Type ULARGE_INTEGER LowPart As integer HighPart As integer End Type Declare Function GetDiskFreeSpaceEx Lib "kernel32.dll" Alias "GetDiskFreeSpaceExA" (ByVal lpDirectoryName As String, lpFreeBytesAvailableToCaller As ULARGE_INTEGER , lpTotalNumberOfBytes As ULARGE_INTEGER, lpTotalNumberOfFreeBytes As ULARGE_INTEGER ) As integer declare sub main dim lpDirectoryName as string dim lpFreeBytesAvailableToCaller, lpTotalNumberOfBytes, lpTotalNumberOfFreeBytes As ULARGE_INTEGER dim return as string sub main lpDirectoryName="c:\data\" if GetDiskFreeSpaceEx(lpDirectoryName,lpFreeBytesAvailableToCaller, lpTotalNumberOfBytes, lpTotalNumberOfFreeBytes)>0 then return=str$(-lpTotalNumberOfFreeBytes.lowpart) if (lpTotalNumberOfFreeBytes.highpart)>0 then return=return+str$(lpTotalNumberOfFreeBytes.highpart) end if note "Free bytes on : "+lpDirectoryName+chr$(10)+chr$(10)+return else note "problem with call to GetDiskFreeSpaceEx" end if end sub
Source: mapinfo-l
MapInfo-Fenster anordnen
Unter Win 32/NT kann folgender MapBasic-Code verwendet werden, um Fenster innerhalb von MapInfo Professional anzuordnen:
Type TRect Left As Integer Top As Integer Right As Integer Bottom As Integer End Type Declare Function GetClientRect Lib "user32" (ByVal hWnd As Integer, rc As TRect) As Integer Dim hMiMdi As Integer, rct As TRect hMiMdi = FindMDIClient(WindowInfo(WIN_MAPINFO, WIN_INFO_WND)) If hMiMdi <> 0 Then Call GetClientRect(hMiMdi, rct) End If ' Now, you have size of MapInfo MDI client in rct variable. ' Its Left and Top fields ' are 0, which is normal for GetClientRect function result. ' rct.Right and rct.Bottom ' contain width and height of this window, in pixels. ' To adjust size and position of another MapInfo windows ' within this window (document ' windows such as maps and browsers are children of ' hMiMdi window), use this (iNumID ' is a numeric window identifier, for example, ' got by FrontWindow() or WindowID(0)): Declare Function MoveWindow Lib "user" (ByVal hWnd, ByVal x, ByVal y, ByVal cx, ByVal cy, ByVal repaint As Integer) As Integer Dim iLeft, iTop, iWidth, iHeight, r, iWnd As Integer iWnd = WindowInfo(iNumID, WIN_INFO_WND) iLeft = 0 iTop = 0 iWidth = rct.Right/2 iHeight = rct.Bottom r = MoveWindow(iWnd, iLeft, iTop, iWidth, iHeight, 1) ' This makes MapInfo window iNumID to fill left half of MapInfo MDI client.
Date Label Formatting
Source: mapinfo-l
To get Data label formatting in label expressions to convert, for example, 01/01/2001 in the data table to format as 1st January 2001 you can try the following:
Day(Dt)+Mid$("stndrdthththththththththththththththththstndrdthththththththst ",Day(Dt)*2-1,2)+" "+ RTrim$(Mid$("January February March April May June July August SeptemberOctober November December ",Month(Dt)*9-8,9))+" "+Year(Dt)
Dateien in Verzeichnis
Unter Win 32/NT kann folgender MapBasic-Code verwendet werden, um der Reihe nach alle Dateien eines Verzeichnisses „anzupacken“. In dem Beispiel wird nach allen DLL-Files im WinNT\System32-Verzeichnis gesucht.
Include "MapBasic.def" Define MAX_PATH 260 Define ERROR_NO_MORE_FILES 18 Define INVALID_HANDLE_VALUE -1 Type FILETIME dwLowDateTime As Integer dwHighDateTime As Integer End Type Type WIN32_FIND_DATA dwFileAttributes As Integer ftCreationTime As FILETIME ftLastAccessTime As FILETIME ftLastWriteTime As FILETIME nFileSizeHigh As Integer nFileSizeLow As Integer dwReserved0 As Integer dwReserved1 As Integer cFileName As String * MAX_PATH cAlternate As String * 14 End Type Declare Function FindFirstFile Lib "kernel32" Alias "FindFirstFileA" (ByVal lpFileName As String, lpFindFileData As WIN32_FIND_DATA) As Integer Declare Function FindNextFile Lib "kernel32" Alias "FindNextFileA" (ByVal hFindFile As Integer, lpFindFileData As WIN32_FIND_DATA) As Integer Declare Function FindClose Lib "kernel32" Alias "FindClose" (ByVal hFindFile As Integer) As Integer Declare Sub Main Sub Main Dim hndl As Integer, fileinfo As WIN32_FIND_DATA hndl = FindFirstFile("c:\winnt\system32\*.dll", fileinfo) If hndl <> INVALID_HANDLE_VALUE Then Do Print fileinfo.cFileName If FindNextFile(hndl, fileinfo) <> 1 Then Exit Do End If Loop While TRUE End If End Sub
Fensterposition bestimmen
Bei der Anwendungsentwicklung ist es sinnvoll, die Platzierung neuer Fenster nicht dem Zufall zu übelassen, sondern sie gezielt zu positionieren.
Um die Lage interaktiv erstmal zu bestimmen, kann ein Fenster geöffnet und dann interaktiv in seiner Größe angepaßt werden, bis ein ansprechendes Ergebnis erreicht ist.
Über die Eingabe der folgenden MapBasic-Anweisungen können nun die Positionierungsangaben in Zentimeter bestimmt werden:
set paper units "cm" print WindowInfo(FrontWindow(),4) + ", " + WindowInfo(FrontWindow(),5) + ", " + WindowInfo(FrontWindow(),6) + ", " + WindowInfo(FrontWindow(),7)
Die Ergebniswerte sind dann Breite, Höhe, Abstand von links, Abstand von oben.
Setzen von Schriftarten
Der Textfont für die verschiedenen MapInfo-Fenstertypen kann über folgende MapBasic-Anweisungen gesetzt werden:
Include "mapbasic.def" Declare Sub Main Declare sub WinFocusChangedHandler Sub Main Set Window Info Font ("MS Sans Serif",0,9,0) Set Window Ruler Font ("MS Sans Serif",0,9,0) Set Window Message Font ("MS Sans Serif",0,9,0) Set Window Statistics Font ("MS Sans Serif",0,9,0) End Sub Sub WinFocusChangedHandler If WindowInfo(CommandInfo(CMD_INFO_WIN),WIN_INFO_TYPE) = WIN_BROWSER Then Set Window FrontWindow() Font("MS Sans Serif",0,9,0) End If End Sub
Überspringen gelöschter Records
Wenn eine Relation gelöschte Einträge enthält (d.h. nach dem Löschen von Objekten nicht gepackt wurde), kann unsauberes Programmieren in der Form
For i = 1 To TableInfo(Table, TAB_INFO_NROWS) Fetch Rec i From Table ... Next
zu Programmabstürzen führen. Um die gelöschten Datensätze zu überspringen, ist folgendermaßen vorzugehen:
Fetch First From Table While Not EOT(Table) ... Fetch Next From Table Wend
Koordinatensysteme
Setzen des MapInfo-Applikationstitels
Der MapInfo-Applikationstitel kann durch Nutzen der Systemfunktion SetWindowText anwendungsspezifisch gesetzt werden, wie es der folgende Code-Abschnitt zeigt.
Declare Function SetWindowText Lib "user32" Alias "SetWindowTextA" (ByVal hwnd As Integer, ByVal lpString As String) As Integer sub set_title dim r as integer r = SetWindowText(windowinfo(win_mapinfo, win_info_wnd), "New Title") end sub
Universal Translator API
Information about opened tables and columns in tables
Source: MAPINFO-L
' ************************************************************************** ' A couple of utility functions to make MapBasic Life easier. ' dcOpenTable( Path, Name ) -- opens a table if it's not already open ' dcCheckOrCreateColumn ( Table, ColName, ColType ) -- create a column if it doesn't exist ' ' Designed to be linked to your program. ' Include "dctabl.def" in your main routine to define the functions. ' include "mapbasic.def" Include "c:\projects\bes pfp\pfptools\dctabl.def" ' ====================================================================== ' dcIsTableOpen ' ====================================================================== Function dcIsTableOpen(ByVal sTableName as String) as Logical Dim l as Logical OnError goto NotOpen l = TableInfo(sTableName, TAB_INFO_READONLY) OnError Goto 0 dcIsTableOpen = TRUE Exit Function NotOpen: OnError goto 0 dcIsTableOpen = FALSE Exit Function End Function ' ====================================================================== ' dcOpenTable ' Path The file path, not including tablename ' of the physical location of the table in case ' it needs to be opened. If the table is already ' open there is no promise that it came from this ' location. ' Name The name of the *.TAB file. ' Alias The Alias used to open the file. ' ====================================================================== Function dcOpenTable(sPathName As String, ByVal sTabName as String, ByVal sAlias as String) As Logical Dim Username as String OnError Goto NotOpen Dim l As Logical ' print "Request is: " + sPathName + sTabname + " as " + sAlias l = TableInfo(sAlias, TAB_INFO_READONLY) dcOpenTable = TRUE Exit Function OpenTable: OnError goto NoTable If Right$(sPathName, 1) <> "\" then sPathName = sPathName + "\" End If UserName = sPathName + sTabName DlgName: ' print "Trying to open " + Username + " as " + sAlias Open Table Username as sAlias OnError goto 0 sPathName = PathToDirectory$(UserName) dcOpenTable = TRUE Exit Function NotOpen: ' print "Not open..." dcOpenTable = FALSE Resume OpenTable NoTable: ' print "Unable to open..." UserName = FileOpenDLG(sPathName, sTabName, "TAB", "Please locate table: " + sAlias + " (" + sPathName + sTabname + ")" ) If Username = "" Then dcOpenTable = FALSE Exit Function Else Resume DlgName End If End Function ' ====================================================================== ' ' ' ====================================================================== Function dcIsColumnThere(ByVal sTabName as String, sColName as String) as Logical Dim NumCols as Integer Dim LoopCount as Integer Dim ColQuery as String Dim ColName as String dcIsColumnThere = FALSE ' See if the column name exists... NumCols = TableInfo (sTabName, TAB_INFO_NCOLS) For LoopCount = 1 to NumCols ColQuery = "Col" + LTrim$(str$(LoopCount)) ColName = ColumnInfo(sTabname, ColQuery, COL_INFO_NAME) If ColName = sColName then dcIsColumnThere = TRUE Exit Function End IF Next End Function ' ====================================================================== ' dcCheckOrCreateColumn ' TableName The alias of the table containing the column ' ColName The name of the column to check for ' ColType The data type if the column needs to be created. ' ' Assumes the table is open... ' Further, does not check to see that the data type matches if the column ' already exists. ' ' ====================================================================== Function dcCheckOrCreateColumn( ByVal sTabName as string, ByVal sColname as string, ByVal SColType as String ) as Logical Dim AlterTableText as String If NOT dcIsColumnThere (sTabName, sColname) Then ' The column name does not exist. Commit Table sTabName AlterTableText = "Alter Table " + sTabname + " (Add " + sColname + " " + sColType + ")" Run Command AlterTableText End If dcCheckorCreateColumn = TRUE End Function ================================================================ ============ here's the content of dctabl.def ================== Declare Function dcOpenTable(sPathName as String, ByVal sTabName As String, ByVal sAlias as String) As Logical Declare Function dcCheckOrCreateColumn( ByVal sTabname as String, ByVal sColname as string, ByVal sColType as string) as Logical Declare Function dcIsTableOpen(ByVal sTable as String) as Logical Declare Function dcIsColumnThere(ByVal sTable as String, sColName as String) as Logical
I recommend WP or another free CMS. As an Internet Service Provider I recommend Strato.de