powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / FoxPro, Visual FoxPro [игнор отключен] [закрыт для гостей] / Как быстро перекинуть неизвестный dbf в Excel? (+)
25 сообщений из 26, страница 1 из 2
Как быстро перекинуть неизвестный dbf в Excel? (+)
    #33183305
Yuri Tyurin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Хорошего дня!

Коллеги, тут юзеры поставили задачку: нужно сделать небольшую утилитку, которая могла бы взять ЛЮБОЙ dbf и перебросить в Excel. Количество записей заранее неизвестно, но запросто может оказаться больше 65536, которые Excel допускает на лист, поэтому приходится делать разбивку по листам. Прогу написал - но уж больно долго она работает... Три-десять строчек в секунду в зависимости от мощности компа и количества полей в таблице, а оно запросто может быть под 200. Код вот такой:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
  oleXL = CreateObject('Excel.Sheet')
  ExcObj = oleXL.ActiveSheet
  oleXL.Application.Visible=.F.
  page_n = 1
  ExcObj.Name = 'Page'+alltrim(str(page_n))

  for i = 1 to n_fp
    ExcObj.Cells(01,i).Value = Field(i,'fp')
  endfor
  i = 2
  
  scan
    if i = 65000 then
      oleXL.Sheets.Add(Null,oleXL.Sheets('Page'+alltrim(str(page_n))),1)
      ExcObj = oleXL.ActiveSheet
      page_n = page_n + 1
      ExcObj.Name = 'Page'+alltrim(str(page_n))
      for i = 1 to n_fp
        ExcObj.Cells(01,i).Value = Field(i,'fp')
      endfor
      i = 2
    endif
    for j = 1 to n_fp
      n_field = 'fp.'+alltrim(Field(j,'fp'))
      ExcObj.Cells(i,j).Value = &n_field
    endfor
    i = i + 1
  endscan

Как вы думаете, можно что-то улучшить? Может есть какие-функции, позволяющие кидать строку в эксель не перебором полей а чем-то вроде копи-паста? ;)

Заранее спасибо!
Юрий.
_______________________________________________________
Обходя разложенные грабли, ты теряешь драгоценный опыт!
...
Рейтинг: 0 / 0
Как быстро перекинуть неизвестный dbf в Excel? (+)
    #33183328
AleksMed
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Как вариант, COPY TO или EXPORT с разбивкой по 65000 записей в разные файлы и затем сбор листов в одну книгу.
...
Рейтинг: 0 / 0
Как быстро перекинуть неизвестный dbf в Excel? (+)
    #33183333
AleksMed
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Или COPY TO ARRAY порциями по 65000 элементов и вставкой в Эксель с разбивкой по листам.
...
Рейтинг: 0 / 0
Как быстро перекинуть неизвестный dbf в Excel? (+)
    #33183391
Фотография ВладимирМ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ну, есть такая штука

_VFP.DataToClip()

Т.е. логика работы с ней примерно такая

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
* Создаем объект Excel
LOCAL loExcel
loExcel=CREATEOBJECT('Excel.Application')

* Создаем в нем новую рабочую книгу
LOCAL loBook
#DEFINE xlWBATWorksheet - 4167 
loBook = m.loExcel.workbooks.Add(xlWBATWorksheet)

* Создаем ссылку на новый лист в рабочей книге
LOCAL loSheet
loSheet = m.loBook.Sheets( 1 )

* Делаем Excel видимым
* Эту команду надо давать в самом конце формирования листа Excel
* здесь она приведена для наглядности
loExcel.Visible= .T.

LOCAL lnNextSheet
lnNextSheet =  0 
select MyTab
FOR lnI= 1  TO Reccount("MyTab") STEP  65000 

	GO m.lnI IN MyTab
	
	lnNextSheet = m.lnNextSheet+ 1 
	IF m.lnNextSheet>m.loBook.Sheets.count
		* Добавляю один новый чистый лист после последнего
		loSheet = m.loBook.Sheets.Add(NULL,m.loSheet, 1 )
	ENDIF

	* Сохраняем текущее значение буфера обмена
	LOCAL lcClipText
	lcClipText = _clipText
	* вставляем в буфер обмена очередные  65000  строк
	_VFP.DataToClip("MyTab", 65000 , 3 )
	* копируем буфер обмена в нужное место Excel
	m.loSheet.Cells( 1 , 1 ).PasteSpecial( 1 )
	* Чтобы снять выделение по окончании всех вставок передаю фокус на первую ячейку
	m.loSheet.Cells( 1 , 1 ).select
	* восстанавливаем буфер обмена
	_clipText = m.lcClipText	
ENDFOR

Ну, еще надо проверить, чтобы не было превышение 255 листов (если записей больше чем 65000*255=16,575,000). Тогда уже новый файл надо создавать. И на каждом листе надо будет удалить строку с именами полей (если они мешают)
...
Рейтинг: 0 / 0
Как быстро перекинуть неизвестный dbf в Excel? (+)
    #33183436
Yuri Tyurin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ВладимирМНу, есть такая штука

_VFP.DataToClip()

...
Ну, еще надо проверить, чтобы не было превышение 255 листов (если записей больше чем 65000*255=16,575,000). Тогда уже новый файл надо создавать. И на каждом листе надо будет удалить строку с именами полей (если они мешают)

Спасибо! :)
...
Рейтинг: 0 / 0
Как быстро перекинуть неизвестный dbf в Excel? (+)
    #33183483
leaf
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Владимир снимаю шляпу ....
каждый день новая инфа и где Вы ее берете? Тока не говорите что в хелпе
шутка, а вообще очень впечатляет
...
Рейтинг: 0 / 0
Как быстро перекинуть неизвестный dbf в Excel? (+)
    #33183795
Фотография ВладимирМ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
leafкаждый день новая инфа и где Вы ее берете? Тока не говорите что в хелпе
Да вопросы постоянно повторяются. Просто, так сказать, "под разным углом". Вот я и выдираю куски ответов на разные вопросы и компаную как бы новый ответ. Ну, и не забываю читать, что же отвечают другие люди на те же вопросы. Остается просто запомнить если не сам ответ, то его идею.

Заданный вопрос настолько часто повторяется, что уже вроде как пора ссылки давать. Просто этот вопрос задают немного в другом виде: Как ускорить экспорт данных в Excel? И он не подразумевает простого копирования содержимого таблицы. Т.е. заданный вопрос - это упрощенный вариант более сложного, но и более часто задаваемого вопроса.
...
Рейтинг: 0 / 0
Как быстро перекинуть неизвестный dbf в Excel? (+)
    #33183923
piva
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Тут давеча - обсуждали - на Foxclub как раз работу DataToClip - тормоз обоалденный чпок
проще оказалось
Select * from ...
copy to ... as 866
в Экселе - открыть DBF таблу
Было намного быстрее
...
Рейтинг: 0 / 0
Как быстро перекинуть неизвестный dbf в Excel? (+)
    #33184074
Фотография ВладимирМ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
pivaТут давеча - обсуждали - на Foxclub как раз работу DataToClip - тормоз обалденный
Вообще-то, этого следовало ожидать. Ведь как физически можно загнать такую кучу записей в буфер обмена? Только просканировав таблицу. Вот на сканирование и уходит основная масса времени.

Кстати, не пробовал сравнить скорость DataToClip() и прямое сканирование (SCAN+TRANSFORM()). Подозреваю, что скорость будет сопоставима.

pivaпроще оказалось
Select * from ...
copy to ... as 866
в Экселе - открыть DBF таблу
Было намного быстрее
В данном случае сброс в DBF не пройдет. Надо ведь копировать данные в разные листы одного файла . А открыть DBF - означает открыть новый файл , а не новый лист.

Правда, можно попробовать выполнить копирование из этого открытого файла на лист другого файла и удалить "промежуточный" файл. Надо будет как-нибудь попробовать.
...
Рейтинг: 0 / 0
Как быстро перекинуть неизвестный dbf в Excel? (+)
    #33184110
w3d
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ВладимирМВедь как физически можно загнать такую кучу записей в буфер обмена?
У меня вот тут появилось такое предложение: а что, если таблицу сначала сохранить на диск, а потом (в процессе переноса) работать с этим файлом как с обычным нетипизированым ( это я на днях паскалем занимался- осталось :)) в смысле - напрямую из файла читать?
...
Рейтинг: 0 / 0
Как быстро перекинуть неизвестный dbf в Excel? (+)
    #33184212
Станислав C.
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
w3d ВладимирМВедь как физически можно загнать такую кучу записей в буфер обмена?
У меня вот тут появилось такое предложение: а что, если таблицу сначала сохранить на диск, а потом (в процессе переноса) работать с этим файлом как с обычным нетипизированым ( это я на днях паскалем занимался- осталось :)) в смысле - напрямую из файла читать?
Ну-ну... А перед этим надо сначала прочитать структуру (заголовок) dbf-ки чтобы правильно парсить строку на отдельные поля и т.д... Фактически делать то, чем Фокс занимается по умолчанию... Если Вы это реализуете как внешнюю программу, например, на С/С++, то, может быть, скорость обработки слегка возрастет... Но если Вы это будете делать под Фоксом, то, вероятнее всего, скорость уменьшится...
Отсюда возникает следующий вопрос:"А оно Вам нужно?!"...
...
Рейтинг: 0 / 0
Как быстро перекинуть неизвестный dbf в Excel? (+)
    #33184231
w3d
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Станислав C. w3d ВладимирМВедь как физически можно загнать такую кучу записей в буфер обмена?
У меня вот тут появилось такое предложение: а что, если таблицу сначала сохранить на диск, а потом (в процессе переноса) работать с этим файлом как с обычным нетипизированым ( это я на днях паскалем занимался- осталось :)) в смысле - напрямую из файла читать?
Ну-ну... А перед этим надо сначала прочитать структуру (заголовок) dbf-ки чтобы правильно парсить строку на отдельные поля и т.д... Фактически делать то, чем Фокс занимается по умолчанию... Если Вы это реализуете как внешнюю программу, например, на С/С++, то, может быть, скорость обработки слегка возрастет... Но если Вы это будете делать под Фоксом, то, вероятнее всего, скорость уменьшится...
Отсюда возникает следующий вопрос:"А оно Вам нужно?!"...
Да я в принципе и не настаиваю :)
Просто возникла такая идея - вот и хотелось бы узнать, в чем она изначально ошибочна :)
...
Рейтинг: 0 / 0
Как быстро перекинуть неизвестный dbf в Excel? (+)
    #33184633
leaf
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
2piva & ВладимирМ

а как Вам такая идея :
выборка в курсор с формированием одного поля из строки таблицы
с разделителями ес..тест..но
и потом сканом в эксель на разные листы в первую колонку каждого листа
квадратно-гнездовым методом ....
В хелпе этого нет так что не пинайте ..... просто Ваше мнение?
Так просто в голову взбрело
...
Рейтинг: 0 / 0
Как быстро перекинуть неизвестный dbf в Excel? (+)
    #33184815
Фотография ВладимирМ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
leaf2piva & ВладимирМ

а как Вам такая идея :
выборка в курсор с формированием одного поля из строки таблицы
с разделителями ес..тест..но
и потом сканом в эксель на разные листы в первую колонку каждого листа
квадратно-гнездовым методом ....
В хелпе этого нет так что не пинайте ..... просто Ваше мнение?
Так просто в голову взбрело
Можно попробовать другую идею на основе "выборки в другое место"

Код: plaintext
1.
2.
3.
COPY TO Sheet1.txt NEXT  65000  TYPE DELIMITED WITH TAB
_ClipText = FileToStr("Sheet1.txt")
m.loSheet.Cells( 1 , 1 ).PasteSpecial( 1 )

Проверил. Это работает. Правда как тут со скоростью не сравнивал. Много времени может занять "затягивание" файла в буфер обмена.
...
Рейтинг: 0 / 0
Как быстро перекинуть неизвестный dbf в Excel? (+)
    #33185272
Yuri Tyurin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ВладимирМНу, есть такая штука

_VFP.DataToClip()

Ну, еще надо проверить, чтобы не было превышение 255 листов (если записей больше чем 65000*255=16,575,000). Тогда уже новый файл надо создавать. И на каждом листе надо будет удалить строку с именами полей (если они мешают)

Увы, этот вариант не прошел, :( хоть и хорош. :) Просто, библиотеки не прописаны и из-за дурацкой политики безопасности на фирме их прописывать никому никуда не дают. :( Пришлось воспользоваться советом ALeksMed. Одна только проблема - когда информация из промежуточной книги Excel скопирована и она закрывается, Excel выдает предупреждение, что в ClipBoard остался огромный кусок инфы и не сохранить ли её для дальнейшей работы. Не подскажете, как это безобразие подавить и очищать ClipBoard, так как информация в нем безусловно уже не нужна?
...
Рейтинг: 0 / 0
Как быстро перекинуть неизвестный dbf в Excel? (+)
    #33185333
AleksMed
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
1. loXls.DisplayAlerts=.F. - спрашивать не будет
2. Про очистку буфера
...
Рейтинг: 0 / 0
Как быстро перекинуть неизвестный dbf в Excel? (+)
    #33185364
Yuri Tyurin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AleksMed1. loXls.DisplayAlerts=.F. - спрашивать не будет
2. Про очистку буфера

Еще раз спасибо! :)
...
Рейтинг: 0 / 0
Как быстро перекинуть неизвестный dbf в Excel? (+)
    #33185365
Фотография ВладимирМ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Yuri Tyurin ВладимирМНу, есть такая штука

_VFP.DataToClip()


Увы, этот вариант не прошел, :( хоть и хорош. :) Просто, библиотеки не прописаны и из-за дурацкой политики безопасности на фирме их прописывать никому никуда не дают.
О каких библиотеках идет речь? Вроде бы здесь нет сторонних библиотек. _VFP.DataToClip() - это родной метод FoxPro. Кажется, введен в VFP5. Если запустили FoxPro, то автоматом запустили и эти библиотеки.

Поробуйте через текстовый файл и FileToStr() с прямой записью в буфер через _ClipText.
...
Рейтинг: 0 / 0
Как быстро перекинуть неизвестный dbf в Excel? (+)
    #33185405
AleksMed
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
2 ВладимирМ

ИМХО DataToClip() имеет еще одно маленькое/большое неудобство: скопированные данные имеют шанс схлеснуться в клипбоарде с данными скопированными из других приложений, маловероятно, НО могут.
...
Рейтинг: 0 / 0
Как быстро перекинуть неизвестный dbf в Excel? (+)
    #33185482
Yuri Tyurin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ВладимирМ Yuri Tyurin ВладимирМНу, есть такая штука

_VFP.DataToClip()


Увы, этот вариант не прошел, :( хоть и хорош. :) Просто, библиотеки не прописаны и из-за дурацкой политики безопасности на фирме их прописывать никому никуда не дают.
О каких библиотеках идет речь? Вроде бы здесь нет сторонних библиотек. _VFP.DataToClip() - это родной метод FoxPro. Кажется, введен в VFP5. Если запустили FoxPro, то автоматом запустили и эти библиотеки.

Поробуйте через текстовый файл и FileToStr() с прямой записью в буфер через _ClipText.

Владимир, тут ситуация такая - даже FoxPro у нас устанавливается... прямым копированием каталога Visual FoxPro 6.0 с CD. То есть он запускается, но в регистре винды его как бы и нет. Видимо поэтому он вчера сразу же ругнулся на отсутствие библиотеки: OLE Error Code 0x8002801d: библиотека не зарегистрирована. Руководители компании (а они сидят не в РФ) все время боятся, что у них информацию сопрут, поэтому заблокировано всё, что только можно.

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
Насчет _ClipText - супер! Всё заработало, кроме одного - русский текст в кракозябрах. :( Пробовал сохранять файл и так:
    COPY TO &file_n FOR between(recno(),rec_fr,rec_to) DELIMITED WITH TAB AS 866
    _ClipText = FileToStr(file_n)
    oleXL.ActiveSheet.Paste
и так:
    COPY TO &file_n FOR between(recno(),rec_fr,rec_to) DELIMITED WITH TAB AS 1251
    _ClipText = FileToStr(file_n)
    oleXL.ActiveSheet.Paste
без толку. 

Что-то где-то не настраиваю?
...
Рейтинг: 0 / 0
Как быстро перекинуть неизвестный dbf в Excel? (+)
    #33185491
Фотография ВладимирМ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Файл CONFIG.FPW (это обычный текстовый файл) со строкой

CODEPAGE = 1251

лежит рядом с EXE?
...
Рейтинг: 0 / 0
Как быстро перекинуть неизвестный dbf в Excel? (+)
    #33185514
Yuri Tyurin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ВладимирМФайл CONFIG.FPW (это обычный текстовый файл) со строкой

CODEPAGE = 1251

лежит рядом с EXE?

Уже лежит. :) А всё равно тоже самое получается. :( Как вариант - может влиять то, что база, на которой я обкатываю прогу, была в свое время конвертирована из Excel в формат Dbase IV и при открытии в VFP6 ей была присовена страница 866?
...
Рейтинг: 0 / 0
Как быстро перекинуть неизвестный dbf в Excel? (+)
    #33185534
Yuri Tyurin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AleksMed1. loXls.DisplayAlerts=.F. - спрашивать не будет
2. Про очистку буфера

Вот, обошёл буфер, прямое копирование с листа на лист:

Код: plaintext
1.
2.
3.
    COPY TO &file_n FOR between(recno(),rec_fr,rec_to) TYPE XL5
    oleXL.WorkBooks.Open(file_n)
    oleXL.ActiveSheet.Cells.Select
    oleXL.Selection.Copy(ExcObj.Sheets('Page'+alltrim(str(page_n))).Cells(1,1))

Заработало!
...
Рейтинг: 0 / 0
Как быстро перекинуть неизвестный dbf в Excel? (+)
    #33185560
Фотография ВладимирМ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Yuri TyurinКак вариант - может влиять то, что база, на которой я обкатываю прогу, была в свое время конвертирована из Excel в формат Dbase IV и при открытии в VFP6 ей была присовена страница 866?
Нет, не может. Разумеется, если у нее явно прописана кодовая страница и текстовый файл получается читаемый сам по себе.

Здесь может быть глюк операционки. Теоретически, надо сделать исправление в реестре НА КЛИЕНТСКОЙ машине. Там где работа с буфером происходит.

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Nls\CodePage]
"1252"="c_1251.nls"

Если админ не позволит, то проверить, виноват ли именно реестр или что-то еще можно проверить следующим образом.

Если результат зависит от текущей раскладки клавиатуры (при английской - все в порядке, при русской - закорючки), значит виноват именно этот ключ реестра.

Впрочем, если обошел буфер, тем лучше, поскольку действительно может вклиниться пользователь пока идет работа с буфером и все испортить...
...
Рейтинг: 0 / 0
Как быстро перекинуть неизвестный dbf в Excel? (+)
    #33185650
Yuri Tyurin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ВладимирМЗдесь может быть глюк операционки. Теоретически, надо сделать исправление в реестре НА КЛИЕНТСКОЙ машине. Там где работа с буфером происходит.

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Nls\CodePage]
"1252"="c_1251.nls"

Если админ не позволит, то проверить, виноват ли именно реестр или что-то еще можно проверить следующим образом.

Если результат зависит от текущей раскладки клавиатуры (при английской - все в порядке, при русской - закорючки), значит виноват именно этот ключ реестра.

Впрочем, если обошел буфер, тем лучше, поскольку действительно может вклиниться пользователь пока идет работа с буфером и все испортить...

Марррразм! ) Но именно так все и оказалось! ) Только наоборот - при включенной русской раскладке текст нормальный, при английской - кракозябры. Спасибо!

Но всё таки, наверно, оставлю мой вариант с копированием без буфера. Пользователи уже попробовали - их всё устраивает, да и действительно надёжней. :)
...
Рейтинг: 0 / 0
25 сообщений из 26, страница 1 из 2
Форумы / FoxPro, Visual FoxPro [игнор отключен] [закрыт для гостей] / Как быстро перекинуть неизвестный dbf в Excel? (+)
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]