Найти тему
Некто

Статья 14. Вывод данных из dbf файла в другой dbf на VBScript с использованием ADO. Работа с dbf файлами. Обмен данными, фильтры, сортировка

В 1 самой начальной статье была рассмотрена работа с dbf и EXCEL. Но процесс работы с несколькими dbf файлами тогда не входило в обсуждение. Потом в статье 11 рассмотрели работу с несколькими EXCEL файлами. Теперь пришел черед обосновать работу с dbf. В своих статьях я уделил много знаний по работе с 3 самыми востребованными форматами. Это текстовый формат (обычно привычно TXT), EXCEL файлы и dbf файлы. Каждый по своему расположит их по применимости исходя из своих видов предпочтений. Материалы по MDB, SQL, XML и другим есть в ИНТЕРНЕТЕ но, по-моему, они не так известны большинству, чтобы думать о них и демонстрировать здесь работу с ними. В ИНТЕРНЕТЕ приведено много примеров работы. Если кому это надо тот всегда найдет и ознакомиться. Самый доступный формат из этой тройки это текстовый, потом EXCEL, а далее dbf. Это также можно понять по возможности с ними работать. Сейчас очень многие работают с EXCEL форматом. Написано очень много книг, причем одна может противоречить другой. Но тот, кто внимательно читает, всегда может эти противоречия распознать. Я думаю, и это мое личное мнение, что полностью EXCEL не знает никто и даже сами разработчики. Я это понимаю по моим программам. Мне иногда говорят, а мы сделали такую комбинацию и ускорили решение, хотя Я рассчитывал другое. Так же и разработчики EXCEL делали одно, но из этого одно те, кто работали, находили другой путь, и лучше. Файл формат dbf, был придуман давно. Имел много версий своей разработки, но все-таки получил распространение, и многие приложения разработаны и продвинуты на работу с этим форматом. Кто работает с программными продуктами и разрабатывает программы, все это знают. Это последняя статья по ADO. Здесь я расскажу про dbf файлы, обмен данными между ними, сортировку, фильтры и удаление записей. Те, кто читал мои статьи, могут сделать определенный вывод. Можно сочетать эти 3 формата и на их основе построить базовое направление работы с данными. Я подготовил несколько файлов скриптов по работе с в dbf форматом. Это файлы AdoED14A.vbs, AdoED14B.vbs, AdoED14C.vbs. В файле AdoED14A.vbs, рассмотрен алгоритм создания нового dbf файла, и перенос данных в файл. Можно сказать так есть один dbf файл. По ходу работы создается другой новый файл и вся структура и данные из 1 файла переносятся в этот.

Я думаю это вроде понятно. В AdoED14C.vbs 2 файла уже существуют и имеют разную структуру, но с некоторыми данными имеют сходство. Так вот в 2 файле добавляются поля, которые нужны для понятия удаления и данные из одного файла, переносят в другой, заменяя определенные данные, а потом возвращают их обратно. Создается фильтр и с помощью него отбираются удаленные записи. Потом эти записи выводятся на экран и записываются в файл. Вывод на экран можно отменить, если данных очень много, потому что это время вывода. Все зависит от мощности фильтра. Возвращают также первоначальную структуру второго файла. Данные другого файла в некотором случае совпадают с данными этого файла. В этом случае создаются два канала, с помощью которых это можно проделать. На AdoED14B.vbs остановимся подробно. В нем есть информации для размышления. В каталоге присутствуют 2 dbf фала _111.dbf и _333.dbf . 3 файл _222.dbf создается в процессе работы AdoED14B.vbs и имеет такую же начальную структуру как _111.dbf. Потом добавляются 3 поля для определенной работы. Предоставляю файл AdoED14B.vbs

По ходу изложения приложу некоторые комментарии.

'*******************************************************************

' Имя: AdoED14B.vbs

' Язык: VBScript

' Описание: Вывод данных из одного DBF файла в другой DBF файл

' Полностью ODBC для dBase, ADO Изменение данных готового файла DBF

' Показ записей помеченных на удаление и удаление записей через RecordSet

' Создание нового файла после фильтра

'*******************************************************************

' On Error Resume Next 'Проверка ошибок

Set WshShell=WScript.CreateObject("WScript.Shell")

SDefaultDir=WshShell.CurrentDirectory

Set FSO = CreateObject("Scripting.FileSystemObject")

' ==== DBF ====

NameFilDBF=SDefaultDir & "\_111.dbf"

NameFilDBF1=SDefaultDir & "\_222.dbf" 'файл создается

'========== Проверка файла

If FSO.FileExists(NameFilDBF) Then

else

MsgBox "Нет файла "&NameFilDBF

WScript.Quit

end if

'========== Проверка файла

'=========== Проверка файла

If FSO.FileExists(NameFilDBF1) Then

'MsgBox "Файл есть! Удаляем"

FSO.DeleteFile NameFilDBF1

End if

'========== Проверка файла

'=================== dBase ==================

Set RSN=WScript.CreateObject("ADODB.Recordset")

Set conn = CreateObject("ADODB.Connection")

SConnect="Driver={Microsoft dBase Driver (*.dbf)};DBQ=" & SDefaultDir & ";"

conn.CursorLocation = 3

conn.Open "Driver={Microsoft dBase Driver (*.dbf)};DBQ=" & SDefaultDir & ";"

strSQLdbf="SELECT * FROM " & NameFilDBF & " "

Set RS = conn.Execute(strSQLdbf)

objKlRecs=RS.RecordCount 'Количество строк в DBF файле

objKlFields = RS.Fields.count 'Количество колонок в DBF файле

'=================== dBase ==================

' ==============Ввод названий Полей базы данных

SQL="create table " & NameFilDBF1 & "("

for i=0 to objKlFields-1

st=RS.Fields(i).Name

stDL= RS.Fields(i).DefinedSize

TypePl=RS.Fields(i).Type

if i=objKlFields-1 then

SQL=SQL & "st" & i & " char(" & stDL & "))"

else

SQL=SQL & "st" & i & " char(" & stDL & "),"

end if

next

RSN.open SQL,conn,3

' ==============Ввод названий Полей базы данных

'Добавляем поля

conn.Execute("ALTER TABLE _222.dbf ADD COLUMN str4 CHAR(5)")

conn.Execute("ALTER TABLE _222.dbf ADD COLUMN str5 CHAR(10)")

conn.Execute("ALTER TABLE _222.dbf ADD COLUMN str10 CHAR(15)")

' ======== Кодировка 866 =======

Set oFile = FSO.GetFile(NameFilDBF1)

With oFile.OpenAsTextStream()

readBinary = .Read(oFile.Size)

.Close

End With

readBinary=left(readBinary,29)+"e"+mid(readBinary,31)

With FSO.createTextFile(NameFilDBF1)

.Write(readBinary)

.Close

End With

' ======== Кодировка 866 =======

for i=1 to objKlRecs

vvv="'"

stN="("

for j=0 to objKlFields-1

st=RS.Fields(j)

'stName=RS.Fields(j).Name

stName="st"&j ' Вводим свои имена полей

if j=objKlFields-1 then

stN=stN & stName & ")"

vvv=vvv & st & "'"

else

stN=stN & stName & ","

vvv=vvv & st & "'" & "," & "'"

end if

next

SQL="insert into " & NameFilDBF1 & " " & stN & " values(" & vvv & ")"

RSN.open SQL,conn,3

RS.MoveNext

next

'+++++++++++++++++++++ Снова открываем коннект и записываем данные

conn.close

SConnect="Driver={Microsoft dBase Driver (*.dbf)};DBQ=" & SDefaultDir & ";Deleted=0;"

'SConnect="Driver={Microsoft dBase Driver (*.dbf)};DBQ=" & SDefaultDir & ";Deleted=0;ReadOnly=0;Exclusive=1;" ' Можно и так

conn.Open SConnect

conn.CursorLocation = 3

strSQLnew="SELECT * FROM " & NameFilDBF1 & " "

RSN.open strSQLnew,conn,1,3

'+++++++++++++++++++++ Делаем поиск и записываем в один файл

' Вот в этом фрагменте мы в файле _222.dbf в поиске по месяцу изменяем данные в 3 поле

RSN.Find "[st1] = 'январь'"

RSN.Fields(3).value="07"

RSN.Update

strSQLdbf="SELECT * FROM " & NameFilDBF & " "

Set RS = conn.Execute(strSQLdbf)

conn.CursorLocation = 3

objKlRecs=RS.RecordCount 'Количество строк в DBF файле

objKlFields = RS.Fields.count 'Количество колонок в DBF файле

'Здесь в фале _111.dbf в поле 1 (месяцы), ищем методом перебора месяц февраль и считываем данные следующего поля и заменяем в файле _222.dbf данные в 3 поле.

RS.MoveFirst

for i=1 to objKlRecs

if RS.Fields(1).value="февраль" then

std1=RS.Fields(2).value

end if

RS.MoveNext

next

RSN.Find "[st1] = 'февраль'"

RSN.Fields(3).value=std1

RSN.Update

'+++++++++++++++++++++ Снова открываем коннект и записываем данные в другой файл

conn.close

'SConnect="Driver={Microsoft dBase Driver (*.dbf)};DBQ=" & SDefaultDir & ";Deleted=0;"

SConnect="Driver={Microsoft dBase Driver (*.dbf)};DBQ=" & SDefaultDir & ";Deleted=0;ReadOnly=0;Exclusive=1;"

conn.Open SConnect

conn.CursorLocation = 3

'Открываем файл _111.dbf и делаем поиск в поле M (месяцы), а в поле 2 записываем данные 07. Потом снова возвращаем предыдущие данные. Проходимся по файлам из одного в другой и обратно.

RSN.open strSQLdbf,conn,1,3

RSN.Find "[M] = 'февраль'"

RSN.Fields(2).value="07"

RSN.Update

' Вернули данные

RSN.Find "[M] = 'февраль'"

RSN.Fields(2).value=std1

RSN.Update

'+++++++++++++++++++++ Снова открываем коннект и показываем помеченные записи на удаление

conn.close

SConnect="Driver={Microsoft dBase Driver (*.dbf)};DBQ=" & SDefaultDir & ";Deleted=0;"

' SConnect="Driver={Microsoft dBase Driver (*.dbf)};DBQ=" & SDefaultDir & ";Deleted=0;ReadOnly=0;Exclusive=1;" ' можно и так

conn.Open SConnect

conn.CursorLocation = 3

strSQLnew="SELECT * FROM " & NameFilDBF1 & " "

Set RS = conn.Execute(strSQLnew)

objKlRecs=RS.RecordCount 'Количество строк в DBF файле

'Изменяем в файле _222.dbf в поле str5 все данные на 0.

SQlupd="update" & NameFilDBF1 & " set [str5] ='0'" ' Ставим 0 для дальнейшей выборки

conn.Execute(SQlupd) ' Изменяем на 0

RSN.open strSQLnew,conn,1,3 ' Открываем

' ********************************* Фрагмент 1 ***************

' Можно таким способом пометить все записи на 0

' RSN.MoveFirst

' for i=1 to objKlRecs

' RSN.Fields(4).value="0"

' RSN.Update

' RSN.MoveNext

' next

' SQlupd="update " & NameFilDBF1 & " set [str5] ='0'"

' conn.Execute(SQlupd)

' *********************************** Фрагмент ***************

'Удаляем запись (помечаем на удаление) в файле _222.dbf согласно полю st1(месяцы).

RSN.MoveFirst

RSN.Find "[st1] = 'май'"

RSN.Fields(4).value="1"

RSN.delete

RSN.Update

RSN.Requery

' ********************************* Фрагмент 2 ***************

' SQLdl="DELETE FROM " & NameFilDBF1 & " " 'Если надо то удаляем все данные, но потом не сможем проводить дальнейшие действия

' conn.Execute(SQLdl)

' ********************************* Фрагмент 1 ***************

SQlupd="update " & NameFilDBF1 & " set [str5] ='1'"

SQlupd=SQlupd & " where [st1] ='июнь'"

conn.Execute(SQlupd) ' Изменяем на 1

SQLdl="DELETE FROM " & NameFilDBF1

SQLdl=SQLdl & " where [st1] ='июнь'"

conn.Execute(SQLdl) ' Удаляем эту запись

'+++++++++++++++++++++ Снова открываем коннект и показываем помеченные записи на удаление

conn.close

SConnect="Driver={Microsoft dBase Driver (*.dbf)};DBQ=" & SDefaultDir & ";Deleted=0;"

'SConnect="Driver={Microsoft dBase Driver (*.dbf)};DBQ=" & SDefaultDir & ";Deleted=0;ReadOnly=0;Exclusive=1;"

conn.Open SConnect

conn.CursorLocation = 3

'wwwwwwwwwwwwwwww 1 вариант wwwwwwwwwwwww

strSQLnew="SELECT * FROM " & NameFilDBF1 & " "

Set RS = conn.Execute(strSQLnew)

v=RS.GetString ' Просмотр этой ситуации когда когда выбраны все записи 1 вариант

wscript.echo("1 вариант" & vbNewLine & v)

'wwwwwwwwwwwwwwww 2 вариант Удаление по фильтру wwwwwwwwwwwww

RSN.open strSQLnew,conn,1,3

'Делаем фильтр по полю st1 (месяцы) в файле _222.dbf и записываем в поле 4 (str5) величину 1 вместо 0

RSN.filter="[st1]>='март'"

Kzap=RSN.RecordCount ' кол. отобранных записей

for i=1 to Kzap

RSN.Fields(4).value="1"

RSN.delete

RSN.MoveNext

next

RSN.Requery

'uuuuuuuuuuuuuuuuuu Можно и так перед этим удалите строки for i=1 to Kzap и т.д.

' SQlupd="update " & NameFilDBF1 & " set [str5] ='1'"

' SQlupd=SQlupd & " where [st1]>='март'"

' conn.Execute(SQlupd) ' Изменяем на 1

' RSN.Requery

'uuuuuuuuuuuuuuuuuu

RSN.MoveFirst

v=RSN.GetString

wscript.echo("2 вариант " & vbNewLine & v)

RSN.filter=0 ' Отменяет фильтр

Kzap=0 ' Очищаем переменную

' &&&&&&&&&&&&&&&&&&&&&&& Создание нового файла &&&&&&&&&&&&&&&&&&&&&&&&&&&

conn.close

SConnect="Driver={Microsoft dBase Driver (*.dbf)};DBQ=" & SDefaultDir & ";Deleted=0;"

conn.Open SConnect

conn.CursorLocation = 3

'Делаем выбор всех данных в зависимости от поля 4 (str5), которые не соответствуют величине 1 в файле _222.dbf и записываем снова в файл. Перед этим файл удаляем.

' strSQLnew="SELECT * FROM " & NameFilDBF1 & " where str5<>'1'"

' Можно сделать сортировку

strSQLnew="SELECT * FROM " & NameFilDBF1 & " where str5<>'1' ORDER BY st2"

Set RS = conn.Execute(strSQLnew)

objKlRecs=RS.RecordCount 'Количество строк в DBF файле

objKlFields = RS.Fields.count 'Количество колонок в DBF файле

ReDim MassFields(objKlFields-1) ' записываем данные полей

strSQlDelNlist="DROP TABLE " & NameFilDBF1 & " " ' Удаляем файл

conn.Execute(strSQlDelNlist)

' ==============Ввод названий Полей базы данных

SQL="create table " & NameFilDBF1 & "("

for i=0 to objKlFields-1

st=RS.Fields(i).Name

stDL= RS.Fields(i).DefinedSize

TypePl=RS.Fields(i).Type

if i=objKlFields-1 then

SQL=SQL & st & " char(" & stDL & "))"

else

SQL=SQL & st & " char(" & stDL & "),"

end if

next

' ==============Ввод названий Полей базы данных

RSN.open SQL,conn,3

' ======== Кодировка 866 =======

Set oFile = FSO.GetFile(NameFilDBF1)

With oFile.OpenAsTextStream()

readBinary = .Read(oFile.Size)

.Close

End With

readBinary=left(readBinary,29)+"e"+mid(readBinary,31)

With FSO.createTextFile(NameFilDBF1)

.Write(readBinary)

.Close

End With

' ======== Кодировка 866 =======

for i=1 to objKlRecs

vvv="'"

stN="("

for j=0 to objKlFields-1

st=RS.Fields(j)

stName=RS.Fields(j).Name

if j=objKlFields-1 then

stN=stN & stName & ")"

vvv=vvv & st & "'"

else

stN=stN & stName & ","

vvv=vvv & st & "'" & "," & "'"

end if

next

SQL="insert into " & NameFilDBF1 & " " & stN & " values(" & vvv & ")"

RSN.open SQL,conn,3

RS.MoveNext

next

'wwwwwwwwwwwwwwww Итог wwwwwwwwwwwww

RS.MoveFirst

v=RS.GetString

wscript.echo("Итог " & vbNewLine & v)

Set FSO = Nothing

RS.close

Set RS = Nothing

Set RSN = Nothing

conn.close

Set conn = Nothing

WScript.Echo("Файл создан!")

WScript.Quit

'Записи в файле dbf физически не удаляются, а помечаются на удаление. В ADO нет решения по физической очистке помеченных на удаление записей. В секретных материалах ADO Я не нашел такой процедуры и поэтому для действия полностью удаления записей из файла приходится удалять сам файл и заново его создавать. Этим я как бы физически удаляю помеченные записи на удаление. В общем, в ADO как в FOXPRO нет PACK (упаковка – освобождение от помеченных на удаление записей) и ZAP (полностью физическое удаление всех записей)

Остальное как обычно.

Можно отредактировать и снова в EXCEL и в текстовый файл.

Как я в предыдущих статьях указал - круговорот данных в масштабных понятиях работы с данными.

Вообще для чего все это нужно и надо бы. С помощью VBScript и JScript можно выявить многие полезные события и свойства ОС, устройств и соединений которые можно скинуть в таблицы с последующим их применением или просто просмотром для личной информации и сведений. Можно скрипт поставить в автозагрузку и подружиться с антивирусом. Потом проверять эти полученные сведения. Конечно, сейчас написано столько программ и приложений, что можно применять и их. Но некоторые приложения платные, а другие тяжелые по своей работе и понятию. В общем, все в Вашем понимании и предпочтении.

Я заканчиваю цикл статей об ADO (некоторые указывают ADODB) и в следующих публикациях перейду к занятиям по ADOX. Что такое ADOX полностью описывать не буду. Откройте ИНТЕРНЕТ и наберите ADOX и найдете много материала об этом направлении. Скажу только что это дополнение к ADO или библиотека-помощь для основных объектов ADO.

Перед запуском скриптов файл _111.dbf и _333.dbf сохраните в другом каталоге для повторного применения, если случайно испортите или удалите.

Процесс переноса данных из больших dbf файлов также может быть долгим и зависит от размера и объема этого файла и мощности компьютера.

Все файлы сохранил в архив Файлы14.rar

Пробуйте.

Ссылка на файл https://disk.yandex.ru/d/enCHARDs9rZ_gA

Подписывайтесь на мой канал и ставьте лайки.