Домашняя страница Undo Do Save Карта сайта Обратная связь Поиск по форуму
МИР MS EXCEL - Гость.xls

Вход

Регистрация

Напомнить пароль

 

= Мир MS Excel/Можно ли ускор.процесс перекач.данных из табл.Exc. в массив? - Мир MS Excel

Старая форма входа
  • Страница 1 из 1
  • 1
Модератор форума: _Boroda_, китин  
Можно ли ускор.процесс перекач.данных из табл.Exc. в массив?
tvitaly1 Дата: Четверг, 04.09.2014, 00:54 | Сообщение № 1
Группа: Пользователи
Ранг: Новичок
Сообщений: 26
Репутация: 0 ±
Замечаний: 0% ±

Excel 2003, Excel 2010
Около 3000 строк в таблице Excel. Перекачиваю данные в массив в приложении Word.
Перекачивание происходит долго.
Можно ли ускорить процесс?..
NS,NS1 тип Long

[vba]
Код
'создаем указатель на Excel приложение
Set app = CreateObject("Excel.Application")
app.workbooks.Open path1
NS = 1
NS1 = 2
app.ActiveWorkbook.Worksheets("таблица перекодировок").Activate

While app.ActiveWorkbook.activesheet.Cells(NS1, 1).Text <> "" Or app.ActiveWorkbook.activesheet.Cells(NS1, 2).Text <> ""

buff(NS, 1) = app.ActiveWorkbook.activesheet.Cells(NS1, 1).Value
If buff(NS, 1) = "" Then
buff(NS, 1) = "'"
End If
buff(NS, 2) = app.ActiveWorkbook.activesheet.Cells(NS1, 2).Value
If buff(NS, 2) = "" Then
buff(NS, 2) = "'"
End If
buff(NS, 3) = app.ActiveWorkbook.activesheet.Cells(NS1, 3).Value
NS = NS + 1
If viv = 1 Then
Application.Caption = "Ждите, идет загрузка таблицы перекодировок " & NS
Else
UserForm3.Caption = "Ждите, идет загрузка таблицы перекодировок " & NS
End If
NS1 = NS1 + 1
Wend

NS = NS - 1
app.workbooks(1).Close
[/vba]
[moder]Для оформления кода используйте теги (кнопка #)[/moder]
 
Ответить
СообщениеОколо 3000 строк в таблице Excel. Перекачиваю данные в массив в приложении Word.
Перекачивание происходит долго.
Можно ли ускорить процесс?..
NS,NS1 тип Long

[vba]
Код
'создаем указатель на Excel приложение
Set app = CreateObject("Excel.Application")
app.workbooks.Open path1
NS = 1
NS1 = 2
app.ActiveWorkbook.Worksheets("таблица перекодировок").Activate

While app.ActiveWorkbook.activesheet.Cells(NS1, 1).Text <> "" Or app.ActiveWorkbook.activesheet.Cells(NS1, 2).Text <> ""

buff(NS, 1) = app.ActiveWorkbook.activesheet.Cells(NS1, 1).Value
If buff(NS, 1) = "" Then
buff(NS, 1) = "'"
End If
buff(NS, 2) = app.ActiveWorkbook.activesheet.Cells(NS1, 2).Value
If buff(NS, 2) = "" Then
buff(NS, 2) = "'"
End If
buff(NS, 3) = app.ActiveWorkbook.activesheet.Cells(NS1, 3).Value
NS = NS + 1
If viv = 1 Then
Application.Caption = "Ждите, идет загрузка таблицы перекодировок " & NS
Else
UserForm3.Caption = "Ждите, идет загрузка таблицы перекодировок " & NS
End If
NS1 = NS1 + 1
Wend

NS = NS - 1
app.workbooks(1).Close
[/vba]
[moder]Для оформления кода используйте теги (кнопка #)[/moder]

Автор - tvitaly1
Дата добавления - 04.09.2014 в 00:54
RAN Дата: Четверг, 04.09.2014, 19:58 | Сообщение № 2
Группа: Друзья
Ранг: Экселист
Сообщений: 5660
Репутация: 1163 ±
Замечаний: 0% ±

2010
Судя по фрагменту кода, можно, и весьма существенно.


Быть или не быть, вот в чем загвоздка!
 
Ответить
СообщениеСудя по фрагменту кода, можно, и весьма существенно.

Автор - RAN
Дата добавления - 04.09.2014 в 19:58
tvitaly1 Дата: Четверг, 04.09.2014, 22:21 | Сообщение № 3
Группа: Пользователи
Ранг: Новичок
Сообщений: 26
Репутация: 0 ±
Замечаний: 0% ±

Excel 2003, Excel 2010
И что вы предлагаете?
 
Ответить
СообщениеИ что вы предлагаете?

Автор - tvitaly1
Дата добавления - 04.09.2014 в 22:21
AndreTM Дата: Четверг, 04.09.2014, 22:38 | Сообщение № 4
Группа: Друзья
Ранг: Старожил
Сообщений: 1762
Репутация: 501 ±
Замечаний: 0% ±

2003 & 2010
Самые большие задержки - из-за использования .Activate и .Active***, можно сделать так, например:
[vba]
Код
...
Set app = CreateObject("Excel.Application")
Set wb= app.workbooks.Open path1
       NS = 1
       NS1 = 2
Set sh =  wb.Worksheets("таблица перекодировок")

While len(sh.Cells(NS1, 1).Text & sh.Cells(NS1, 2).Text)>0

       buff(NS, 1) = sh.Cells(NS1, 1).Value
...
[/vba]

Далее, - зачем проверять viv внутри цикла? Можно просто вынести вывод вне его. Другое дело, если нужно отслеживать процесс выполнения - (как в исходной части кода по счётчику) - но смысл? При увеличении производительности кода - время исполнения цикла будет достаточно малым, а вот отображение (да ещё построчно, а не, например, процентно) - достаточно затратный процесс.
[vba]
Код
...
Set sh =  wb.Worksheets("таблица перекодировок")

If viv = 1 Then
       Application.Caption = "Ждите, идет загрузка таблицы перекодировок "
Else
       UserForm3.Caption = "Ждите, идет загрузка таблицы перекодировок "
End If

While len(sh.Cells(NS1, 1).Text & sh.Cells(NS1, 2).Text)>0
...
[/vba]

Ну и как дополнение - неясно, как организовано выделение памяти под массив buff. Если он постоянно динамически переопределяется - ещё куда ни шло заполнение его внутри цикла. Это с расчётом на дополнительные условия для ячеек. В противном случае - привыкайте к тому, что любой набор ячеек - и так является массивом памяти. И получить его можно прямым копированием:
[vba]
Код
ns1_0 = ns1
While len(sh.Cells(NS1, 1).Text & sh.Cells(NS1, 2).Text )>0
       ns1 = ns1 + 1
Wend
ns1 = ns1 - 1
ReDim buff (1 To (ns1 - ns1_0 + 1), 1 To 3)
buff = Range(sh.Cells(NS1_0, 1), sh.Cells(NS1, 3))
[/vba]
и далее работаем только с массивом.


Skype: andre.tm.007
Donate: Qiwi: 9517375010


Сообщение отредактировал AndreTM - Четверг, 04.09.2014, 22:51
 
Ответить
СообщениеСамые большие задержки - из-за использования .Activate и .Active***, можно сделать так, например:
[vba]
Код
...
Set app = CreateObject("Excel.Application")
Set wb= app.workbooks.Open path1
       NS = 1
       NS1 = 2
Set sh =  wb.Worksheets("таблица перекодировок")

While len(sh.Cells(NS1, 1).Text & sh.Cells(NS1, 2).Text)>0

       buff(NS, 1) = sh.Cells(NS1, 1).Value
...
[/vba]

Далее, - зачем проверять viv внутри цикла? Можно просто вынести вывод вне его. Другое дело, если нужно отслеживать процесс выполнения - (как в исходной части кода по счётчику) - но смысл? При увеличении производительности кода - время исполнения цикла будет достаточно малым, а вот отображение (да ещё построчно, а не, например, процентно) - достаточно затратный процесс.
[vba]
Код
...
Set sh =  wb.Worksheets("таблица перекодировок")

If viv = 1 Then
       Application.Caption = "Ждите, идет загрузка таблицы перекодировок "
Else
       UserForm3.Caption = "Ждите, идет загрузка таблицы перекодировок "
End If

While len(sh.Cells(NS1, 1).Text & sh.Cells(NS1, 2).Text)>0
...
[/vba]

Ну и как дополнение - неясно, как организовано выделение памяти под массив buff. Если он постоянно динамически переопределяется - ещё куда ни шло заполнение его внутри цикла. Это с расчётом на дополнительные условия для ячеек. В противном случае - привыкайте к тому, что любой набор ячеек - и так является массивом памяти. И получить его можно прямым копированием:
[vba]
Код
ns1_0 = ns1
While len(sh.Cells(NS1, 1).Text & sh.Cells(NS1, 2).Text )>0
       ns1 = ns1 + 1
Wend
ns1 = ns1 - 1
ReDim buff (1 To (ns1 - ns1_0 + 1), 1 To 3)
buff = Range(sh.Cells(NS1_0, 1), sh.Cells(NS1, 3))
[/vba]
и далее работаем только с массивом.

Автор - AndreTM
Дата добавления - 04.09.2014 в 22:38
tvitaly1 Дата: Четверг, 04.09.2014, 23:08 | Сообщение № 5
Группа: Пользователи
Ранг: Новичок
Сообщений: 26
Репутация: 0 ±
Замечаний: 0% ±

Excel 2003, Excel 2010
AndreTM, спасибо большое за вашу помощь. Учту ваши предложения и попробую. О вещах представленных в 3 примере вообще не знал.
 
Ответить
СообщениеAndreTM, спасибо большое за вашу помощь. Учту ваши предложения и попробую. О вещах представленных в 3 примере вообще не знал.

Автор - tvitaly1
Дата добавления - 04.09.2014 в 23:08
AndreTM Дата: Четверг, 04.09.2014, 23:30 | Сообщение № 6
Группа: Друзья
Ранг: Старожил
Сообщений: 1762
Репутация: 501 ±
Замечаний: 0% ±

2003 & 2010
О вещах представленных в 3 примере вообще не знал.
Ну, как бы это все обычно упоминается, но, почему-то, очень вскользь. Яркий пример - работа с .ListBox через его свойство .List.
А в целом - всё очень просто. Прямое копирование "область листа - массив памяти" предусмотрено изначально. Ошибка начинающих - это неверное указание границ (массив в этом случае должен обязательно иметь в качестве нижнего маржина значение 1 (а не дефолный 0)). Обмен при этом двусторонний - вы можете не только считать .Range в массив, но и записать массив напрямую в .Range.
Кроме того, обработка "собственного" массива данных, естественно, происходит намного быстрее, поскольку ячейка листа - всё же объект модели, со всеми наследуемыми зависисмостями. А вот собственный массив - только ваша память из кучи, где вы будете распоряжаться по собственному усмотрению. И поэтому, кстати, в момент записи массива обратно на лист - рекомендуется "временно" отключать все пересчеты книги (дабы, если уж они зависимы от заменённых ячеек - перерасчёт производился разом по всем обновленным значениям)...


Skype: andre.tm.007
Donate: Qiwi: 9517375010
 
Ответить
Сообщение
О вещах представленных в 3 примере вообще не знал.
Ну, как бы это все обычно упоминается, но, почему-то, очень вскользь. Яркий пример - работа с .ListBox через его свойство .List.
А в целом - всё очень просто. Прямое копирование "область листа - массив памяти" предусмотрено изначально. Ошибка начинающих - это неверное указание границ (массив в этом случае должен обязательно иметь в качестве нижнего маржина значение 1 (а не дефолный 0)). Обмен при этом двусторонний - вы можете не только считать .Range в массив, но и записать массив напрямую в .Range.
Кроме того, обработка "собственного" массива данных, естественно, происходит намного быстрее, поскольку ячейка листа - всё же объект модели, со всеми наследуемыми зависисмостями. А вот собственный массив - только ваша память из кучи, где вы будете распоряжаться по собственному усмотрению. И поэтому, кстати, в момент записи массива обратно на лист - рекомендуется "временно" отключать все пересчеты книги (дабы, если уж они зависимы от заменённых ячеек - перерасчёт производился разом по всем обновленным значениям)...

Автор - AndreTM
Дата добавления - 04.09.2014 в 23:30
tvitaly1 Дата: Четверг, 04.09.2014, 23:45 | Сообщение № 7
Группа: Пользователи
Ранг: Новичок
Сообщений: 26
Репутация: 0 ±
Замечаний: 0% ±

Excel 2003, Excel 2010
Пока попробовал так, быстрее получилось
[vba]
Код
If NS = 0 Then
  s3 = UserForm3.Caption
  'создаем указатель на Excel приложение
   NS = 1
   NS1 = 2
  Set app = CreateObject("Excel.Application")
   app.workbooks.Open path1
   Set wb = app.workbooks(1)
   Set sh = wb.Worksheets("таблица перекодировок")
     If viv = 1 Then
      Set vvv = Application
     Else
      Set vvv = UserForm3
     End If
    
    
    While sh.Cells(NS1, 1).Text & sh.Cells(NS1, 2).Text <> ""
   
       buff(NS, 1) = sh.Cells(NS1, 1).Value
       If buff(NS, 1) = "" Then
       buff(NS, 1) = "'"
       End If
       buff(NS, 2) = sh.Cells(NS1, 2).Value
       If buff(NS, 2) = "" Then
       buff(NS, 2) = "'"
       End If
       buff(NS, 3) = sh.Cells(NS1, 3).Value
       NS = NS + 1
       vvv.Caption = "Ждите, идет загрузка таблицы перекодировок " & NS
     NS1 = NS1 + 1
    Wend
        
   NS = NS - 1
  wb.Close
   
  For i = 1 To NS
    For j = i + 1 To NS
      If Len(buff(i, 1)) < Len(buff(j, 1)) Then
        s = buff(i, 1)
        buff(i, 1) = buff(j, 1)
        buff(j, 1) = s
         
        s = buff(i, 2)
        buff(i, 2) = buff(j, 2)
        buff(j, 2) = s
         
        s = buff(i, 3)
        buff(i, 3) = buff(j, 3)
        buff(j, 3) = s
      End If
    Next j
   Next i
    
  Set app = Nothing
  If viv = 1 Then
   Application.Caption = ""
  Else
   UserForm3.Caption = s3
  End If
  End If
[/vba]
А есть принципиальная разница для скорости так
[vba]
Код
Set wb = app.workbooks(1)
  Set sh = wb.Worksheets("таблица перекодировок")
[/vba]
Или вот так?
[vba]
Код
Set sh = app.workbooks(1).Worksheets("таблица перекодировок")
[/vba]
 
Ответить
СообщениеПока попробовал так, быстрее получилось
[vba]
Код
If NS = 0 Then
  s3 = UserForm3.Caption
  'создаем указатель на Excel приложение
   NS = 1
   NS1 = 2
  Set app = CreateObject("Excel.Application")
   app.workbooks.Open path1
   Set wb = app.workbooks(1)
   Set sh = wb.Worksheets("таблица перекодировок")
     If viv = 1 Then
      Set vvv = Application
     Else
      Set vvv = UserForm3
     End If
    
    
    While sh.Cells(NS1, 1).Text & sh.Cells(NS1, 2).Text <> ""
   
       buff(NS, 1) = sh.Cells(NS1, 1).Value
       If buff(NS, 1) = "" Then
       buff(NS, 1) = "'"
       End If
       buff(NS, 2) = sh.Cells(NS1, 2).Value
       If buff(NS, 2) = "" Then
       buff(NS, 2) = "'"
       End If
       buff(NS, 3) = sh.Cells(NS1, 3).Value
       NS = NS + 1
       vvv.Caption = "Ждите, идет загрузка таблицы перекодировок " & NS
     NS1 = NS1 + 1
    Wend
        
   NS = NS - 1
  wb.Close
   
  For i = 1 To NS
    For j = i + 1 To NS
      If Len(buff(i, 1)) < Len(buff(j, 1)) Then
        s = buff(i, 1)
        buff(i, 1) = buff(j, 1)
        buff(j, 1) = s
         
        s = buff(i, 2)
        buff(i, 2) = buff(j, 2)
        buff(j, 2) = s
         
        s = buff(i, 3)
        buff(i, 3) = buff(j, 3)
        buff(j, 3) = s
      End If
    Next j
   Next i
    
  Set app = Nothing
  If viv = 1 Then
   Application.Caption = ""
  Else
   UserForm3.Caption = s3
  End If
  End If
[/vba]
А есть принципиальная разница для скорости так
[vba]
Код
Set wb = app.workbooks(1)
  Set sh = wb.Worksheets("таблица перекодировок")
[/vba]
Или вот так?
[vba]
Код
Set sh = app.workbooks(1).Worksheets("таблица перекодировок")
[/vba]

Автор - tvitaly1
Дата добавления - 04.09.2014 в 23:45
tvitaly1 Дата: Четверг, 04.09.2014, 23:56 | Сообщение № 8
Группа: Пользователи
Ранг: Новичок
Сообщений: 26
Репутация: 0 ±
Замечаний: 0% ±

Excel 2003, Excel 2010
Ну, как бы это все обычно упоминается, но, почему-то, очень вскользь. Яркий пример - работа с .ListBox через его свойство .List.
А в целом - всё очень просто. Прямое копирование "область листа - массив памяти" предусмотрено изначально. Ошибка начинающих - это неверное указание границ (массив в этом случае должен обязательно иметь в качестве нижнего маржина значение 1 (а не дефолный 0)). Обмен при этом двусторонний - вы можете не только считать .Range в массив, но и записать массив напрямую в .Range.
Кроме того, обработка "собственного" массива данных, естественно, происходит намного быстрее, поскольку ячейка листа - всё же объект модели, со всеми наследуемыми зависисмостями. А вот собственный массив - только ваша память из кучи, где вы будете распоряжаться по собственному усмотрению. И поэтому, кстати, в момент записи массива обратно на лист - рекомендуется "временно" отключать все пересчеты книги (дабы, если уж они зависимы от заменённых ячеек - перерасчёт производился разом по всем обновленным значениям)...

Спасибо, на счет ListBox вспомнил
Пример загрузки данных в списки объектов ListBox1, ComboBox1:

[vba]
Код
‘установить четыре колонки вывода
ListBox1.ColumnCount = 4
‘Задать диапазон ячеек активного листа для копирования
ListBox1.RowSource = "A1: D10"
‘установить две колонки вывода
ComboBox1.ColumnCount = 2  
‘установить ширину колонок вывода
ComboBox1.ColumnWidths = "54;40"
‘Задать диапазон ячеек на листе Аудитория
ComboBox1.RowSource = "'Аудитория'!a1:b100"
[/vba]
 
Ответить
Сообщение
Ну, как бы это все обычно упоминается, но, почему-то, очень вскользь. Яркий пример - работа с .ListBox через его свойство .List.
А в целом - всё очень просто. Прямое копирование "область листа - массив памяти" предусмотрено изначально. Ошибка начинающих - это неверное указание границ (массив в этом случае должен обязательно иметь в качестве нижнего маржина значение 1 (а не дефолный 0)). Обмен при этом двусторонний - вы можете не только считать .Range в массив, но и записать массив напрямую в .Range.
Кроме того, обработка "собственного" массива данных, естественно, происходит намного быстрее, поскольку ячейка листа - всё же объект модели, со всеми наследуемыми зависисмостями. А вот собственный массив - только ваша память из кучи, где вы будете распоряжаться по собственному усмотрению. И поэтому, кстати, в момент записи массива обратно на лист - рекомендуется "временно" отключать все пересчеты книги (дабы, если уж они зависимы от заменённых ячеек - перерасчёт производился разом по всем обновленным значениям)...

Спасибо, на счет ListBox вспомнил
Пример загрузки данных в списки объектов ListBox1, ComboBox1:

[vba]
Код
‘установить четыре колонки вывода
ListBox1.ColumnCount = 4
‘Задать диапазон ячеек активного листа для копирования
ListBox1.RowSource = "A1: D10"
‘установить две колонки вывода
ComboBox1.ColumnCount = 2  
‘установить ширину колонок вывода
ComboBox1.ColumnWidths = "54;40"
‘Задать диапазон ячеек на листе Аудитория
ComboBox1.RowSource = "'Аудитория'!a1:b100"
[/vba]

Автор - tvitaly1
Дата добавления - 04.09.2014 в 23:56
AndreTM Дата: Пятница, 05.09.2014, 00:30 | Сообщение № 9
Группа: Друзья
Ранг: Старожил
Сообщений: 1762
Репутация: 501 ±
Замечаний: 0% ±

2003 & 2010
А что-то типа такого как?


Я, правда, в алгоритм самой обработки не вникал, но, судя по всему, простая сортировка по первому столбцу :) Почему бы тогда вообще не сменить принцип обработки?
0) Открываем _копию_ исходной таблицы.
1) Чистим первый столбец от "мусора" (включая пустые значения). Возможно, чистим второй столбец.
2) Применяем встроенный .Sort для диапазона
Не забываем об отключении пересчета/отображения до работы и включении обратно (хотя и необязательно, раз это отдельный поток приложения) после. И все дела...

Ещё вариант - просто запросить данные из Excel с помощью запроса SQL (MsQuery), со всей обработкой внутри Jet. Неужели Word перестал позволять обращаться к внешним источникам данных? :)

Ну и по вопросу.
А есть принципиальная разница для скорости так
Set wb = app.workbooks(1)
Set sh = wb.Worksheets("таблица перекодировок")

Или вот так?
Set sh = app.workbooks(1).Worksheets("таблица перекодировок")

Дело в том, что app.workbooks(1) - не обязательно открытая вами книга :) Мало ли что там произошло в момент между Create*** и Open. Поэтому и set wb должно быть именно ссылкой на конкретный экземпляр конкретной книги (как я выше приводил в примере). С другой стороны, никакой именно разницы в быстродействии - нет (если обращаетесь правильно) - ведь это просто ссылки, а присвоениее ссылок на разные имена - только для удобства понимания и использования. Ну и не забыть их в конце освободить через = Nothing. Впрочем, это тоже не обязательно - локальные объекты внутри процедур будут уничтожены автоматом.


Skype: andre.tm.007
Donate: Qiwi: 9517375010


Сообщение отредактировал AndreTM - Пятница, 05.09.2014, 00:40
 
Ответить
СообщениеА что-то типа такого как?


Я, правда, в алгоритм самой обработки не вникал, но, судя по всему, простая сортировка по первому столбцу :) Почему бы тогда вообще не сменить принцип обработки?
0) Открываем _копию_ исходной таблицы.
1) Чистим первый столбец от "мусора" (включая пустые значения). Возможно, чистим второй столбец.
2) Применяем встроенный .Sort для диапазона
Не забываем об отключении пересчета/отображения до работы и включении обратно (хотя и необязательно, раз это отдельный поток приложения) после. И все дела...

Ещё вариант - просто запросить данные из Excel с помощью запроса SQL (MsQuery), со всей обработкой внутри Jet. Неужели Word перестал позволять обращаться к внешним источникам данных? :)

Ну и по вопросу.
А есть принципиальная разница для скорости так
Set wb = app.workbooks(1)
Set sh = wb.Worksheets("таблица перекодировок")

Или вот так?
Set sh = app.workbooks(1).Worksheets("таблица перекодировок")

Дело в том, что app.workbooks(1) - не обязательно открытая вами книга :) Мало ли что там произошло в момент между Create*** и Open. Поэтому и set wb должно быть именно ссылкой на конкретный экземпляр конкретной книги (как я выше приводил в примере). С другой стороны, никакой именно разницы в быстродействии - нет (если обращаетесь правильно) - ведь это просто ссылки, а присвоениее ссылок на разные имена - только для удобства понимания и использования. Ну и не забыть их в конце освободить через = Nothing. Впрочем, это тоже не обязательно - локальные объекты внутри процедур будут уничтожены автоматом.

Автор - AndreTM
Дата добавления - 05.09.2014 в 00:30
tvitaly1 Дата: Пятница, 05.09.2014, 02:39 | Сообщение № 10
Группа: Пользователи
Ранг: Новичок
Сообщений: 26
Репутация: 0 ±
Замечаний: 0% ±

Excel 2003, Excel 2010
AndreTM, наконец-то получилось загрузить массив способом, который вы предложили.
Но все равно NS1 вычислять в цикле нужно, и по времени навряд ли будет быстрее.
[vba]
Код
Dim bu()
bu = sh.Range("a2:c" + CStr(NS1 - 1)).Value
MsgBox bu(4, 3)
[/vba]
Но все равно, спасибо за обучение.

P.S.
Попробовал вышеприведенным способом сделать динамический массив buff, но моя программа с динамическим массивом отказывается работать, виснет.
Загрузка идет не так долго, ограничился минимальными переделками.
[vba]
Код
NS = 1
   NS1 = 2
  'ñîçäàåì óêàçàòåëü íà Excel ïðèëîæåíèå
   Set app = CreateObject("Excel.Application")
   app.workbooks.Open path1
   Set wb = app.workbooks(Name1)
   Set sh = wb.Worksheets("òàáëèöà ïåðåêîäèðîâîê")
     If viv = 1 Then
      Set vvv = Application
     Else
      Set vvv = UserForm3
     End If
    
    
    While sh.Cells(NS1, 1).Text & sh.Cells(NS1, 2).Text <> ""
     buff(NS, 1) = sh.Cells(NS1, 1).Text
     buff(NS, 2) = sh.Cells(NS1, 2).Text
     buff(NS, 3) = sh.Cells(NS1, 3).Text
     If buff(NS, 1) = "" Then
       buff(NS, 1) = "'"
     End If
     If buff(NS, 2) = "" Then
       buff(NS, 2) = "'"
     End If
     vvv.Caption = "Æäèòå, èäåò çàãðóçêà òàáëèöû ïåðåêîäèðîâîê " & NS1
     NS = NS + 1
     NS1 = NS1 + 1
    Wend
          
NS = NS - 1

wb.Close
[/vba]
К стати о птичках, в ячейке таблицы Excel есть символ <'> (десятичный код 39), но считывается он из таблицы вышеприведенным способом как пустота.


Сообщение отредактировал tvitaly1 - Пятница, 05.09.2014, 10:03
 
Ответить
СообщениеAndreTM, наконец-то получилось загрузить массив способом, который вы предложили.
Но все равно NS1 вычислять в цикле нужно, и по времени навряд ли будет быстрее.
[vba]
Код
Dim bu()
bu = sh.Range("a2:c" + CStr(NS1 - 1)).Value
MsgBox bu(4, 3)
[/vba]
Но все равно, спасибо за обучение.

P.S.
Попробовал вышеприведенным способом сделать динамический массив buff, но моя программа с динамическим массивом отказывается работать, виснет.
Загрузка идет не так долго, ограничился минимальными переделками.
[vba]
Код
NS = 1
   NS1 = 2
  'ñîçäàåì óêàçàòåëü íà Excel ïðèëîæåíèå
   Set app = CreateObject("Excel.Application")
   app.workbooks.Open path1
   Set wb = app.workbooks(Name1)
   Set sh = wb.Worksheets("òàáëèöà ïåðåêîäèðîâîê")
     If viv = 1 Then
      Set vvv = Application
     Else
      Set vvv = UserForm3
     End If
    
    
    While sh.Cells(NS1, 1).Text & sh.Cells(NS1, 2).Text <> ""
     buff(NS, 1) = sh.Cells(NS1, 1).Text
     buff(NS, 2) = sh.Cells(NS1, 2).Text
     buff(NS, 3) = sh.Cells(NS1, 3).Text
     If buff(NS, 1) = "" Then
       buff(NS, 1) = "'"
     End If
     If buff(NS, 2) = "" Then
       buff(NS, 2) = "'"
     End If
     vvv.Caption = "Æäèòå, èäåò çàãðóçêà òàáëèöû ïåðåêîäèðîâîê " & NS1
     NS = NS + 1
     NS1 = NS1 + 1
    Wend
          
NS = NS - 1

wb.Close
[/vba]
К стати о птичках, в ячейке таблицы Excel есть символ <'> (десятичный код 39), но считывается он из таблицы вышеприведенным способом как пустота.

Автор - tvitaly1
Дата добавления - 05.09.2014 в 02:39
Gustav Дата: Пятница, 05.09.2014, 10:37 | Сообщение № 11
Группа: Админы
Ранг: Участник клуба
Сообщений: 2793
Репутация: 1160 ±
Замечаний: ±

начинал с Excel 4.0, видел 2.1
в ячейке таблицы Excel есть символ <'> (десятичный код 39), но считывается он из таблицы вышеприведенным способом как пустота

Этот апостроф имеет в Excel особый смысл. С его помощью можно, например, ввести в ячейку строку цифр без потери ведущих нулей 000123. Если ввести просто 000123, то в ячейке останется число 123. Если же ввести '000123, то в ячейке будет виден текст 000123 - апостроф отображаться не будет.

Этот апостроф не является частью свойств Range.Value или Range.Text. Но его можно получить отдельно (только зачем?!), используя свойство Range.PrefixCharacter.


МОИ: Ник, Tip box: 41001663842605

Сообщение отредактировал Gustav - Пятница, 05.09.2014, 10:45
 
Ответить
Сообщение
в ячейке таблицы Excel есть символ <'> (десятичный код 39), но считывается он из таблицы вышеприведенным способом как пустота

Этот апостроф имеет в Excel особый смысл. С его помощью можно, например, ввести в ячейку строку цифр без потери ведущих нулей 000123. Если ввести просто 000123, то в ячейке останется число 123. Если же ввести '000123, то в ячейке будет виден текст 000123 - апостроф отображаться не будет.

Этот апостроф не является частью свойств Range.Value или Range.Text. Но его можно получить отдельно (только зачем?!), используя свойство Range.PrefixCharacter.

Автор - Gustav
Дата добавления - 05.09.2014 в 10:37
tvitaly1 Дата: Пятница, 05.09.2014, 11:25 | Сообщение № 12
Группа: Пользователи
Ранг: Новичок
Сообщений: 26
Репутация: 0 ±
Замечаний: 0% ±

Excel 2003, Excel 2010
Спасибо, Gustav, понял в чем дело.
Этот символ у меня используется в Ворд для транслитерации. Пустота в таблице перекодировок у меня все равно не используется, так что оставлю так, как я сделал.

P.S.
Вот так выгладит лучше, но все равно не быстрее :)
[vba]
Код
   NS = 1
     NS1 = sh.Range("A1").SpecialCells(11).Row
      
      For i = 2 To NS1
       buff(NS, 1) = sh.Cells(i, 1).Text
       buff(NS, 2) = sh.Cells(i, 2).Text
       buff(NS, 3) = sh.Cells(i, 3).Text
       'Символ апостроф десятичный код 39 считывается из ячейки таблицы Excel
       'через свойства Value, Text как пустота
       If buff(NS, 1) = "" Then
         buff(NS, 1) = "'"
       End If
       If buff(NS, 2) = "" Then
         buff(NS, 2) = "'"
       End If
       vvv.Caption = "Ждите, идет загрузка таблицы перекодировок " & NS1 & "/" & i
       NS = NS + 1
      Next i
            
   NS = NS - 1
[/vba]


Сообщение отредактировал tvitaly1 - Пятница, 05.09.2014, 15:52
 
Ответить
СообщениеСпасибо, Gustav, понял в чем дело.
Этот символ у меня используется в Ворд для транслитерации. Пустота в таблице перекодировок у меня все равно не используется, так что оставлю так, как я сделал.

P.S.
Вот так выгладит лучше, но все равно не быстрее :)
[vba]
Код
   NS = 1
     NS1 = sh.Range("A1").SpecialCells(11).Row
      
      For i = 2 To NS1
       buff(NS, 1) = sh.Cells(i, 1).Text
       buff(NS, 2) = sh.Cells(i, 2).Text
       buff(NS, 3) = sh.Cells(i, 3).Text
       'Символ апостроф десятичный код 39 считывается из ячейки таблицы Excel
       'через свойства Value, Text как пустота
       If buff(NS, 1) = "" Then
         buff(NS, 1) = "'"
       End If
       If buff(NS, 2) = "" Then
         buff(NS, 2) = "'"
       End If
       vvv.Caption = "Ждите, идет загрузка таблицы перекодировок " & NS1 & "/" & i
       NS = NS + 1
      Next i
            
   NS = NS - 1
[/vba]

Автор - tvitaly1
Дата добавления - 05.09.2014 в 11:25
  • Страница 1 из 1
  • 1
Поиск:

Яндекс.Метрика Яндекс цитирования
© 2010-2024 · Дизайн: MichaelCH · Хостинг от uCoz · При использовании материалов сайта, ссылка на www.excelworld.ru обязательна!