Вся правда о DBF. Шокирующие истории ADODB и немного магии!


Что интересного скрывает ADODB? С чем его едят и как готовить я попробую разобрать.
ADOdb — программная библиотека, обеспечивающая прикладной интерфейс доступа к базам данных для языков программирования PHP и Python, основанная на некоторых концепциях Microsoft ActiveX Data Objects. Библиотека обеспечивает разработчика приложений абстрактным инструментарием, позволяющим создавать приложения без необходимости программирования поддержки каждого из конкретных возможных типов источников данных. В частности, у разработчиков появляется возможность изменить СУБД без необходимости вносить исправления в программный код.(с) Википедия
Википедия не права. На языках программирования PHP и Python все не ограничивается. Этот интерфейс можно использовать практически везде, где есть возможность подключения Microsoft ActiveX Data Objects.
Один из ключевых трюков ADODB заключается в том, что подключаясь к любому источнику данных мы можем делать с ним типовые операции без учета индивидуальных особенностей БД.
Т.е. у нас будут одни и теже запросы как к DBF файлу, так и к базе Firebird.
А теперь немного магии (как и было обещано в заголовке). Если попробовать поискать в интернете "как получить наименования столбцов в DBF файле?" вы найдете это.
Магия в том, что на самом деле это делается так:
Подключаемся к ODBC. Источник данных dBASE Files есть на в любой Windows, но только в х86 версиях.
Чтобы воспользоваться этой программой на х64 нужно запустить её так: "c:\Windows\SysWOW64\wscript.exe имя_скрипта.vbs"
Или скачать х64 ODBC драйвер отсюда и создать ODBC источник с именем dBASE Files вручную

ConnectString = "Provider=MSDASQL.1;Persist Security Info=False;Data Source='dBASE Files';SourceDB='имя файла dbf'"
Set DBConn = CreateObject("ADODB.Connection")
DBConn.Open(ConnectString)
StatusBar.text=Err.Description	
' Тут происходит получение списка столбцов файла и их названий
Set rs = CreateObject("ADODB.Recordset") ' Создаем рекордсет
tablename=имя файла без расширения
rs.open tablename,DBConn ' Открываем таблицу
for i=0 to rs.fields.count-1 ' Нумерация столбцов начинается с 0, перечисляем их все.
		msgbox rs.fields(i).name ' Волшебным образом получаем имя столбца. И выводим его
next

Для такой нетривиальной задачи написано множество вопросов на форумах. Ответ лежал на поверхности вот этого файла с руководством по ADODB.
Далее привожу пример программы, которая может открывать и просматривать любой DBF файл:
Set wso = WScript.CreateObject("Scripting.WindowSystemObject") ' Загружаем WSO
		wso.EnableVisualStyles = true ' Включение поддержки тем оформления
Set objArgs = WScript.Arguments ' Считываем аргументы запуска
	For I = 0 to objArgs.Count - 1 
		Comand=objArgs(I)
	Next 	' В результате нужно получить путь к файлу
set frm = wso.CreateForm(0,0,0,0) ' Формирование главной формы
		frm.ClientWidth = 700
		frm.ClientHeight = 700
		frm.CenterControl()
		frm.Font.Size = 10
set StatusBar = frm.CreateStatusBar() ' Полоска статуса. Туда будем выводить полезные данные
		StatusBar.Add(200).AutoSize = true
		StatusBar.ParentFont = true
		' Создаем ListView 
set LW=frm.CreateListView(0,0, 0, 0,WSO.Translate("LVS_REPORT | LVS_SHOWSELALWAYS")) 
		LW.Align = wso.Translate("AL_CLIENT")
		LW.GridLines = true 
		LW.RowSelect=True  
		LW.ReadOnly=True
		LW.Font.Size=10
		LW.GridLines =true	
	if len(comand)=0 then ' Если длинна аргумента, с которым запущен скрипт =0 то выход
		frm.close()
		wscript.quit()
	end if
	Comand=trim(Comand)
	if Right(Comand, 3)<>"DBF" then ' Проверка расширения файла
		frm.close()
	end if
	' Подключаемся к ODBC. Тут немного магии: источник данных dBASE Files есть на в любой Windows, но только в х86 версиях.
	' Чтобы воспользоваться этой программой на х64 нужно запустить её так: "c:\Windows\SysWOW64\wscript.exe имя_скрипта.vbs"
	' Или скачать х64 ODBC драйвер отсюда http://www.microsoft.com/en-us/download/details.aspx?id=13255 
	' и создать ODBC источник с именем dBASE Files вручную
	ConnectString = "Provider=MSDASQL.1;Persist Security Info=False;Data Source='dBASE Files';SourceDB='"+Comand+"'"
Set DBConn = CreateObject("ADODB.Connection")
	DBConn.Open(ConnectString)
	StatusBar.text=Err.Description	
	' Вот тут уже много магии. Тут происходит получение списка столбцов файла и их названий
Set rs = CreateObject("ADODB.Recordset") ' Создаем рекордсет
	' Надо получить имя таблицы без .dbf и пути
Set objFSO=CreateObject("Scripting.FileSystemObject")
	strName=objFSO.GetFileName(Comand)
	strName=Left(strName, Len(strName)-4)
	rs.open strName,DBConn ' Открываем таблицу
	for i=0 to rs.fields.count-1 ' Нумерация столбцов начинается с 0, перечисляем их все.
		set r1=LW.Columns.Add (rs.fields(i).name, 100) ' Волшебным образом получаем имя столбца. И добавляем колонку в ListView
	next
	sqlstring="SELECT * FROM "+strName ' Запрос всех строк из таблицы
set clmn=DBConn.Execute(sqlstring)	
	y=0
	while not clmn.EOF ' Заполняем таблицу данными из файла
		LW.Add(clmn.Fields(0).Value)
		for i=1 to rs.fields.count-1 ' Вложеный цикл, сначала пробегаем по столбцам, потом по строкам
			val=clmn.Fields(i).Value
			if isnull(val) then ' Проверка пустых значений
				val="NULL"
			end if
			LW.item(y).SubItems(i-1)=Cstr(val)
		next		
		y=y+1
		clmn.movenext ' Переходим к следующей строке
	wend
	frm.text=Comand
	StatusBar.text="Файл открыт. Всего "+Cstr(y+1)+" записей в файле"
frm.Show()
wso.Run()

Этот код нужно сохрантить в формате *.vbs
Для корректной работы потребуется установить WSO.