Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > IT форум > Помощь студентам
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 09.08.2017, 09:48   #1
Ethex
Пользователь
 
Регистрация: 26.04.2017
Сообщений: 86
По умолчанию VBA Access И снова импорт из Word

Доброго времени суток
Весной занимался макросом импорт из word в access (да, такой нужен; word - excel - access в моём случае не вариант). Код уже видели тут, ну вот он:
Код:
Dim app As Word.Application
Dim wd As Word.Document
Dim wt As Word.Table
Dim db As DAO.Database
Dim rs As DAO.Recordset
Dim i As Long

Set app = CreateObject(“Word.Application”)
Set wd = app.DocumentsOpen(Forms![Forma].[Pole].Value)
Set wt = wd.Table(1)
Set db = CurrentDb
Set rs = db.OpenRecordset(“table”)

   With wt
      For I = 4 To Rows.Count
         With rs
         On Error Resume Next
         Add.New
         ![pole] = wt.Cell(i, 1).RangeText
         …
        On Error GoTo 0
        .Update
        End With
      Next
   End With

rst.Close: Set rst = Nothing
dbs.Close: Set rst = Nothing
doc.Close: Set doc = Nothing
appWord.Quit: Set appWord = Nothing
Написал. Заточил под определённую таблицу word. Далее занимался другими вещами, про ворды благополучно забыл. Но далее возникла необходимость импортировать из ворда. Попались многостраничные документы с таблицами овер 20 килострок. И тут стало видно, что такое колличество строк импортируется не просто со скрипом, а с очень жутким скрипом. Импорт мог занять 2+ часов времени. А вернее не сам импорт, а именно обработка данных ворда. Чем больше строк обрабатывается, тем сильнее замедляется программа. Импортировать, скажем, первые 500 строк и импортировать последние 500 той же таблицы - две разные картины по времени.

Я думал как оптимизировать макрос. Занимался различными извращениями. Пытался импортировать по 500 - 1000 строк в цикле, закрывать и открывать документ, аппликейшн, рекордсет внутри цикла - думал, что импортировать не сразу, а по n, но постоянно с новой строки будет быстрее. Ничего более умного по этому вопросу не нашёл, ииии...
Хочу в очередной раз поизгаляться.

Думаю попробовать создать массив на колличество страниц документа. Каждый раз открывать новую страницу и импортировать данные с размещённой на ней таблицы. Знаю как делать такое для листов экселя, а вот с вордом не получается. И возможно ли? Если известен правильный способ оптимизации, то было бы очень здорово. Но и даже если нет, я буду рад узнать как делать постраничный импорт из ворда, пусть он мне и не поможет.
Заранее спасибо
Ethex вне форума Ответить с цитированием
Старый 10.08.2017, 12:03   #2
Ethex
Пользователь
 
Регистрация: 26.04.2017
Сообщений: 86
По умолчанию

Продолжаем
Разбил документ постранично на много файлов. Выбрал мультиселектом файлы, директории в списке. Пытаюсь использовать код:
Код:
Private Sub Кнопка6_Click()
Dim tbls()
Dim cnt As Long
Dim j As Long
cnt = Me!Список0.ListCount - 1
   If Me!Список0.ListCount = 0 Then
   MsgBox "бла-бла
   Exit Sub
   Else 
   CurrentDb.Execute "CREATE TABLE WData (pole VARCHAR, pole VARCHAR, pole VARCHAR, pole VARCHAR)"
   End If
ReDim tbls(0 To cnt)
   For j = 0 To cnt
   tbls(j) = Me.Список0.ItemData(j)
   Next j
ImpW tbls
End Sub

Public Sub ImpW(tbls)
Dim app As Word.Application
Dim wd As Word.Document
Dim wt As Word.Table
Dim db As DAO.Database
Dim rs As DAO.Recordset
Dim i As Long
Dim j As Long
Dim t
Set db = CurrentDb
Set rs = db.OpenRecordset("WData")
Set app = CreateObject("Word.Application")
   For j = 0 To UBound(tbls)
   t = tbls(j)
   Set wd = app.Documents(t)
   Set wt = wd.Tables(1)
      With wt
         For i = 1 To .Rows.Count
            With rs
            On Error Resume Next
            .AddNew
            ![pole] = wt.Cell(i, 2).Range.Text
            ...
            .update
            On Error GoTo 0
            End With
         Next
      End With
   wd.Close: Set wd = Nothing
   Next j
rs.Close: Set rs = Nothing
db.Close: Set db = Nothing
app.Quit: Set app = Nothing
MsgBox "бла-бла"
End Sub
Ругается на открытие документа - Set wd = app.Documents.Open(t). Ошибка - неверное имя файла. Менял t на Me![Список0].ListIndex(j), выдавал ошибку 451
Ethex вне форума Ответить с цитированием
Старый 10.08.2017, 13:50   #3
Ethex
Пользователь
 
Регистрация: 26.04.2017
Сообщений: 86
По умолчанию

Второй пост - отбой тревоги. Причина была в глупой ошибке
Код:
Set wd = app.Documents(t)
Случайно забыл .Open
А такой импорт скорей работает чем нет. Буду дальше тестировать

Update: Потестировал. Импорт 23 килострок с чем-то занимает в районе 7 минут по времени

Последний раз редактировалось Ethex; 10.08.2017 в 15:05.
Ethex вне форума Ответить с цитированием
Старый 11.08.2017, 10:15   #4
Ethex
Пользователь
 
Регистрация: 26.04.2017
Сообщений: 86
По умолчанию

Вот теперь нужна подсказка.
Есть процедура для разбития документа на страницы
Код:
Public Sub SIP()
Dim app As Word.Application
Dim wd As Word.Document
Dim cd As Word.Document
Dim wr As Word.Range
Dim i As Integer
Dim cnt As Integer
Dim fn As String
Set app = CreateObject("Word.Application")
Set wd = app.Documents.Open(Forms![ImpWord].[Поле2].Value)
Set wr = wd.Range
i = 1
cnt = wd.Content.ComputeStatistics(wdStatisticPages)
SysCmd acSysCmdClearStatus
SysCmd acSysCmdInitMeter, "Страницы документа", cnt
   Do Until i > cnt
   SysCmd acSysCmdUpdateMeter, i
      If i = cnt Then
      wr.End = wd.Range.End
      Else
      Selection.Goto wdGoToPage, wdGoToAbsolute, i + 1
      wr.End = Selection.Start
      End If
wr.Copy
Set cd = Documents.Add
cd.Range.Paste
cd.Range.Find.Execute Findtext:="^m", ReplaceWith:=""
fn = Replace(wd.FullName, ".doc", "_" & i & ".doc")
cd.SaveAs fn
i = i + 1
cd.Close
Me!Список0.AddItem Item:=cd.Path
wr.Collapse wdCollapseEnd
Loop
SysCmd acSysCmdClearStatus
Set wd = Nothing
Set cd = Nothing
Set wr = Nothing
End Sub
Мне нужно избавить пользователя от необходимости самому заполнять список, отбирая файлы мультиселектом. Подскажите, как сделать так, чтобы при разделении в список добавлялся путь создаваемого документа?
Пробовал
Код:
...
i = i + 1
cd.Close
Me!Список0.AddItem Item:=cd.Path
...
Выдаёт ошибку автоматизации

Update: Надо
Код:
...
i = i + 1
Me!Список0.AddItem Item:=fn
cd.Close
...

Последний раз редактировалось Ethex; 11.08.2017 в 12:19.
Ethex вне форума Ответить с цитированием
Старый 18.08.2017, 15:30   #5
Ethex
Пользователь
 
Регистрация: 26.04.2017
Сообщений: 86
По умолчанию

Вобщем, сумел оптимизировать импорт
1) выбираем документ
2) разбиваем его постранично (создаваемые документы, в колличестве страниц исходника сохраняются в папку с исходником), добавляя в список на форме путь к каждой из страниц
3) импортируем в одну таблицу данные с каждой из страниц обращась к списку с путями
4) удаляем созданные документы, так же обращаясь к списку; после удаления файла из списка убирается путь к нему; в папке остаётся только исходный документ

Итог: Импорт из документа, занимающий ранее несколько часов, стал занимать 8 - 10 мин (в mdb) и 10 -15 мин (в accdb).
Не стал утруждать себя демонстрацией кода, т.к. не уверен что сюда придёт кто-то, кто вынужден работать с бд в word. Но, по просьбе любого страждущего смогу это сделать
Ethex вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
VBA, Access, Импорт данных Ethex Помощь студентам 5 05.05.2017 22:43
импорт данных из word в excel vba ele-ele Microsoft Office Excel 13 14.10.2016 04:43
И снова объединение ячеек в Word Samkoff Microsoft Office Word 5 13.06.2014 19:28
И снова VBA..... Ingez Помощь студентам 13 09.04.2013 20:46
И снова закрытие файлов Word... hackPNZ Microsoft Office Word 6 29.11.2011 11:04