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

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

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

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

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

Ответ
 
Опции темы Поиск в этой теме
Старый 17.07.2017, 12:39   #1
Ethex
Пользователь
 
Регистрация: 26.04.2017
Сообщений: 86
По умолчанию VBA Access Медленно выполняется процедура импорта

Доброго времени суток
Не знаю насколько это имеет отношение к проблеме, однако в начале прошлой недели на работе сбоило электричество. С тех самых пор я стал
замечать, что процедуры импорта, которые я пишу для форм, выполняются неприлично медленно.
В данный момент имеется форма с опцией выбора нескольких файлов и кнопки для импорта таблиц excel разного типа. Сейчас гоняю импорт таблицы где строк под импорт смешное колличество - 10 (импорт занял 7 минут, при том, что импорт той же таблицы штатным методом происходит мгновенно).
В чём может быть причина?
Используемый код:
- Импорт
Код:
Public Sub ImpChFv()
Dim appX As Excel.Application
Dim wB As Excel.Workbook
Dim wS As Excel.Worksheet
Dim dbs As DAO.Database
Dim rst As DAO.Recordset
Dim rsE As DAO.Recordset
Dim i As Long

Set appX = CreateObject("Excel.Application")
Set wB = appX.Workbooks.Open(Forms![Project].[Поле12].Value)
Set dbs = CurrentDb
Set rst = dbs.OpenRecordset("Таблица")
Set wS = wB.Sheets(1)
   With wS
      For i = 3 To .Rows.Count
         If Len(wS.Cells(i, "B")) > 0 Then
            With rst
            .AddNew
            On Error GoTo ErN
            ![ob] = wS.Cells(i, "A")
            ![naim] = wS.Cells(i, "B")
            ![cod_pogruzka] = wS.Cells(i, "C")
            ![cod_razgruzka] = wS.Cells(i, "D")
            On Error GoTo 0
            .Update
            End With
         End If
      Next
   End With
rst.Close: Set rst = Nothing
dbs.Close: Set rst = Nothing
wB.Close: Set wB = Nothing
appX.Quit: Set appX = Nothing

MsgBox "блабла"

   If DCount("[Name]", "MSysObjects", "[Name] = 'Errors_×àñòü5'") > 0 Then
   MsgBox "блабла"
   End If
Exit Sub
ErN:
   Select Case Err.Number
   Case 3421:
      If DCount("[Name]", "MSysObjects", "[Name]='Errors'") = 0 Then
      CurrentDb.Execute "CREATE TABLE Errors(RowNumbers INT)"
      End If
   Set rsE = dbs.OpenRecordset("Errors")
      With wS
         With rsE
         .AddNew
         ![RowNumbers] = wS.Cells(i, "A")
         .Update
         End With
      End With
   rsE.Close: Set rsE = Nothing
   Resume Next
   End Select
End Sub
- Поиск повторов значений одного из полей
Код:
Public Sub ChFvRep()

   If DCount("[Name]", "MSysObjects", "[Name] = 'Повторы'") > 0 Then
   CurrentDb.Execute "DROP TABLE Повторы"
   End If
   
CurrentDb.Execute "CREATE TABLE Повторы ([ob] VARCHAR)"
CurrentDb.Execute "INSERT INTO Повторы ([ob]) SELECT [ob] FROM ÔÅÐ_×àñòü5"
CurrentDb.Execute "DELETE [ob] FROM [Повторы] WHERE [ob] IN(SELECT [ob] FROM [Повторы] GROUP BY [ob] HAVING COUNT (*) = 1)"
   
   If DCount("*", "Повторы") = 0 Then
   CurrentDb.Execute "DROP TABLE Повторы"
   MsgBox "Повторов не найдено"
   Exit Sub
   End If
   
   If DCount("[Name]", "MSysObjects", "[Name] = Повторы'") > 0 Then
   MsgBox "Найдены повторы"
   End If
End Sub
- Кнопка на форме
Код:
Private Sub Кнопка34_Click()

If IsNull(Forms![Project].[Поле12].Value) Then
   MsgBox "Файл не выбран"
   Exit Sub
   End If
   
On Error GoTo ErS
CurrentDb.Execute "CREATE TABLE Таблица ([ob] VARCHAR, [naim] MEMO, [cod_pogruzka] FLOAT, [cod_razgruzka] FLOAT)"

   If DCount("[Name]", "MSysObjects", "[Name] = 'Errors'") > 0 Then
   CurrentDb.Execute "DROP TABLE Errors5"
   End If
Call ImpChFv
Call ChFvRep
Exit Sub
ErS:
   Select Case Err.Number
   Case 3010:
   MsgBox "Таблица уже существует"
   Exit Sub
   End Select
End Sub
Ранее мне не приходилось работать с такими маленькими таблицами. Импортировал этой процедурой таблицы с более 100 килостроками. Да, не мгновенно, однако время было более-менее адекватное для такого объёма. Уж не знаю сколько теперь будет выполняться импорт таких таблиц, если так долго идёт десятистрочная.

Формат файла акса - mdb, эксельник - xlsx
Библиотеки:
Visual Basic For Applications
Microsoft Access 14.0 Object Library
OLE Automation
Microsoft Office 14.0 Access database engine Object Library
Microsoft ActiveX Data Objects 2.8 Library
Microsoft Visual Basic for Applications Extensibility 5.3
Microsoft Word 14.0 Object Library
Microsoft Office 14.0 Object Library
Microsoft Excel 14.0 Objects Library
Microsft ActiveX Data Objects 2.8 Library
Microsft ActiveX Data Objects Recordset 2.8 Library

На других машинах пока не запускал. Проверю вечером на домашнем ноуте в случае если к тому времени вопрос не будет исчерпан
Ethex вне форума Ответить с цитированием
Старый 17.07.2017, 12:53   #2
Aleksandr H.
2 the Nation Glory
Старожил
 
Аватар для Aleksandr H.
 
Регистрация: 27.05.2014
Сообщений: 3,289
По умолчанию

Размер mdb? Зжатие базы не помогает?
Кто умер, но не забыт, тот бессмертен.
Лао-Цзы.
Aleksandr H. вне форума Ответить с цитированием
Старый 17.07.2017, 13:29   #3
Ethex
Пользователь
 
Регистрация: 26.04.2017
Сообщений: 86
По умолчанию

Цитата:
Размер mdb? Зжатие базы не помогает?
До сжатия 1,73 мб, после 432 кб
Сжимал через Параметры - Сжимать при закрытии

Пару раз попробовал импортнуть - 6 мин.
Ethex вне форума Ответить с цитированием
Старый 17.07.2017, 13:42   #4
Aleksandr H.
2 the Nation Glory
Старожил
 
Аватар для Aleksandr H.
 
Регистрация: 27.05.2014
Сообщений: 3,289
По умолчанию

Еще вариант - пересоздать xlsx файла. Не сохранить как, а нового
Кто умер, но не забыт, тот бессмертен.
Лао-Цзы.
Aleksandr H. вне форума Ответить с цитированием
Старый 17.07.2017, 14:58   #5
Ethex
Пользователь
 
Регистрация: 26.04.2017
Сообщений: 86
По умолчанию

Цитата:
Сообщение от Aleksandr H. Посмотреть сообщение
пересоздать xlsx файла
Создал файлик с 10 строчками - 6 - 7 мин
Поставил на свой страх и риск импортаться книгу с овер 150 килостроками - 20-25 примерно минут, точно не засёк. Хотя по логике должно быть непойми сколько...
Ethex вне форума Ответить с цитированием
Старый 17.07.2017, 15:16   #6
Aleksandr H.
2 the Nation Glory
Старожил
 
Аватар для Aleksandr H.
 
Регистрация: 27.05.2014
Сообщений: 3,289
По умолчанию

Ручная трассировка где показывает задержку выполнения?
Кто умер, но не забыт, тот бессмертен.
Лао-Цзы.
Aleksandr H. вне форума Ответить с цитированием
Старый 17.07.2017, 15:55   #7
Ethex
Пользователь
 
Регистрация: 26.04.2017
Сообщений: 86
По умолчанию

Протрассировал.
Когда заканчиваются непустые строки, выполнение начинает долго прыгать по строкам кода
Код:
If Len(wS.Cells(i, "B")) > 0 Then
Код:
End If
Код:
Next
Минуя With. Похоже, условие проверяет все ячейки указанных столбцов на листе. Но если убрать условие - тогда хренелион пустых ячеек портнётся в аксесс.

Заменить If на Do While?

Последний раз редактировалось Ethex; 17.07.2017 в 16:00.
Ethex вне форума Ответить с цитированием
Старый 17.07.2017, 16:09   #8
Aleksandr H.
2 the Nation Glory
Старожил
 
Аватар для Aleksandr H.
 
Регистрация: 27.05.2014
Сообщений: 3,289
По умолчанию

а такая замена?
Код:
....
With wS
      For i = 3 To .Rows.Count
         If Len(wS.Cells(i, "B")) > 0 Then
....
==>
Код:
....
With wS
      For i = 3 To .Cells(.Rows.Count, "B").End(xlUp).Row
         If Len(wS.Cells(i, "B")) > 0 Then
....
Кто умер, но не забыт, тот бессмертен.
Лао-Цзы.
Aleksandr H. вне форума Ответить с цитированием
Старый 17.07.2017, 17:43   #9
Ethex
Пользователь
 
Регистрация: 26.04.2017
Сообщений: 86
По умолчанию

Цитата:
Сообщение от Aleksandr H. Посмотреть сообщение
а такая замена?
10строчная влетела мгновенно. Та, что большая импортнулась примерно в 1,5 раза быстрее.
Как называется этот метод?
Цитата:
Сообщение от Aleksandr H. Посмотреть сообщение
.Cells(.Rows.Count, "B").End(xlUp).Row
Хочу понять его получше
Ethex вне форума Ответить с цитированием
Старый 17.07.2017, 19:09   #10
Aleksandr H.
2 the Nation Glory
Старожил
 
Аватар для Aleksandr H.
 
Регистрация: 27.05.2014
Сообщений: 3,289
По умолчанию

"найти последнюю непустую ячейку столбца В, при условии что нету фильтров, и получить номер строки этой ячейки"
Кто умер, но не забыт, тот бессмертен.
Лао-Цзы.
Aleksandr H. вне форума Ответить с цитированием
Ответ


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

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
MySQL: Процедура выполняется не полностью lawliet93 SQL, базы данных 0 13.01.2013 15:57
медленно выполняется макрос vefer Microsoft Office Excel 4 22.01.2012 16:35
Не выполняется хранимая процедура MrBlackJack Microsoft Office Excel 0 29.12.2011 10:51
Обновление таблицы Access путем импорта данных из DBF TranzitZP Microsoft Office Access 9 11.04.2011 00:26
Все висит пока выполняется процедура XPAiN Общие вопросы Delphi 3 07.05.2008 15:03