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

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

Вернуться   Форум программистов > Microsoft Office и VBA программирование > Microsoft Office Excel
Регистрация

Восстановить пароль

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

Ответ
 
Опции темы Поиск в этой теме
Старый 31.08.2012, 17:01   #11
staniiislav
Форумчанин
 
Аватар для staniiislav
 
Регистрация: 16.04.2010
Сообщений: 695
По умолчанию

вот еще немного переделал, добавил функцию EducatedFool
Вложения
Тип файла: rar 2.rar (38.6 Кб, 28 просмотров)
Единственный способ стать умнее, играть с более умным противником...
staniiislav вне форума Ответить с цитированием
Старый 31.08.2012, 17:15   #12
Hugo121
Старожил
 
Регистрация: 11.05.2010
Сообщений: 5,170
По умолчанию

А если книг будет сотня? Памяти сразу на все хватит?
MaxxVer - сколько там их может быть всего?
И я бы уж в любом случае не стал их активировать (кстати, код и без активации работает вроде правильно )

P.S. А словарь там зачем?
webmoney: E265281470651 Z422237915069 R418926282008
Hugo121 вне форума Ответить с цитированием
Старый 31.08.2012, 17:26   #13
MaxxVer
Форумчанин
 
Регистрация: 17.03.2009
Сообщений: 226
По умолчанию

Книг порядка 30.
MaxxVer вне форума Ответить с цитированием
Старый 31.08.2012, 17:36   #14
staniiislav
Форумчанин
 
Аватар для staniiislav
 
Регистрация: 16.04.2010
Сообщений: 695
По умолчанию

Цитата:
Сообщение от Hugo121 Посмотреть сообщение
А если книг будет сотня? Памяти сразу на все хватит?
тогда или впр или запрос sql как Вы уже выкладывали

Цитата:
Сообщение от Hugo121 Посмотреть сообщение
И я бы уж в любом случае не стал их активировать (кстати, код и без активации работает вроде правильно )
))) активацией я проверяю есть ли книга или лист, если нет то соответствующее сообщение в ячейку

Цитата:
Сообщение от Hugo121 Посмотреть сообщение
P.S. А словарь там зачем?
со словарем запарился ))) надо убрать, хоте с начало через len перебегать книги, а потом забыл убрать
Единственный способ стать умнее, играть с более умным противником...
staniiislav вне форума Ответить с цитированием
Старый 31.08.2012, 17:44   #15
Hugo121
Старожил
 
Регистрация: 11.05.2010
Сообщений: 5,170
По умолчанию

С SQL никто пока варианта не предложил, только упоминали - но я например не знаю, как можно сделать на SQL без лишнего открытия книг.
Потихоньку думаю, как бы на словарях сделать красиво - но красиво не придумывается

30 книг вероятно потянет.


А с проверкой наличия книги можно иначе сделать, и без активации - но я бы вероятно и тут использовал вместо кода тёзки свой обычный словарь
Т.е. собираем в словарь имена открываемых книг, затем перебором словаря их открываем и сразу смотрим - есть ли ошибка. И сразу в словаре отмечаем - вот эта не открылась.
Затем в коде проверяем уже по словарю - всё ли прошло хорошо.
Конечно, есть риск, что книга вылетит в процессе работы - но она и так может вылететь в любой момент, если система/комп кривые...
webmoney: E265281470651 Z422237915069 R418926282008

Последний раз редактировалось Hugo121; 31.08.2012 в 18:02.
Hugo121 вне форума Ответить с цитированием
Старый 31.08.2012, 18:00   #16
staniiislav
Форумчанин
 
Аватар для staniiislav
 
Регистрация: 16.04.2010
Сообщений: 695
По умолчанию

если будет время на выходных, может что-нить про sql почитаю... глядишь, прозрение придет )))
Единственный способ стать умнее, играть с более умным противником...
staniiislav вне форума Ответить с цитированием
Старый 01.09.2012, 01:24   #17
Hugo121
Старожил
 
Регистрация: 11.05.2010
Сообщений: 5,170
По умолчанию

Сделал то, что было интересно - как файлы открывать только один раз.
Код делал на файле Станислава 2.rar (38.6 Кб) - он выше на этой странице.

Код:
Option Explicit

Sub tt()
    Dim a(), i&, oD_B As Object, oD_BS As Object, wb As Object
    Dim t$, elB, elS, elK, krit$, poz&, calc_status&

    Dim временнаястрока$

    Set oD_B = CreateObject("Scripting.Dictionary")    'книги с листами
    Set oD_BS = CreateObject("Scripting.Dictionary")    'книги|листы с критериями и позициями

    a = [a3].CurrentRegion.Value 'это можно/нужно сделать иначе, не важно как
    ReDim b(1 To UBound(a), 1 To 6) 'массив результатов

    '==== заполняем словари
    For i = 1 To UBound(a)
        t = a(i, 1) & "|" & a(i, 2)    'чтоб сто раз не лазить/делать :)

        If Not oD_B.exists(a(i, 1)) Then    'если книги нет
            oD_B.Item(a(i, 1)) = a(i, 2)    'в книгу лист
            oD_BS.Item(t) = a(i, 3) & "@@" & i    'в кн|лист критерий и позицию
        Else    'если книга есть
            If Not oD_BS.exists(t) Then    'если кн|листа нет
                oD_B.Item(a(i, 1)) = oD_B.Item(a(i, 1)) & "|" & a(i, 2)    'пополняем в книге лист
                oD_BS.Item(t) = a(i, 3) & "@@" & i    'в кн|лист критерий и позицию
            Else
                oD_BS.Item(t) = oD_BS.Item(t) & "|" & a(i, 3) & "@@" & i
            End If
        End If
    Next

    '===== открываем книги, ищем по листам данные
    With Application
        calc_status = .Calculation
        .Calculation = xlManual
        .ScreenUpdating = False
        .EnableEvents = False

        On Error Resume Next
        For Each elB In oD_B    'книги
            Debug.Print "Открываем " & elB
            Set wb = GetObject(ThisWorkbook.Path & "\" & elB & ".xls")
            If Err = 0 Then
                For Each elS In Split(oD_B.Item(elB), "|") 'листы
                    t = oD_BS.Item(elB & "|" & elS)
                    For Each elK In Split(t, "|")
                        krit = Split(elK, "@@")(0)
                        poz = Split(elK, "@@")(1)
                        временнаястрока = "В wb на листе " & elS & " ищем " & krit & ", пишем в " & poz & " строку"
                        Debug.Print временнаястрока
                        'тут собственно всё и происходит :)
                        'можно взять готовый код от staniiislav :)
                        'дополнительно обработать отсутсвие листа
                        'но пишем в объявленный массив
                        b(poz, 1) = временнаястрока
                        'который в финале выгружаем
                    Next
                Next
                Debug.Print "Закрываем " & elB
                wb.Close 0
            Else
                Err.Clear
                For Each elS In Split(oD_B.Item(elB), "|")
                    t = oD_BS.Item(elB & "|" & elS)
                    For Each elK In Split(t, "|")
                        'krit = Split(elK, "@@")(0)'это сейчас не нужно
                        poz = Split(elK, "@@")(1)
                        временнаястрока = "Книга " & elB & " не найдены!"
                        Debug.Print временнаястрока
                        'пишем ошибку
                        b(poz, 1) = временнаястрока
                    Next
                Next
            End If
        Next
        
        On Error GoTo 0
        
        Sheets(1).[d3].Resize(UBound(b, 1), UBound(b, 2)) = b

        .Calculation = calc_status
        .EnableEvents = True
        .ScreenUpdating = True
    End With

End Sub
Книги, листы и даже критерии могут повторяться (по логике комбинация книга/лист/критерий повторяться не должна, но всяко бывает - учёл).
Т.е. в одном конкретном листе можно искать не одного "человека", а сколько угодно (сколько в string поместится).
Позиция вывода естественно повторится физически не может.
webmoney: E265281470651 Z422237915069 R418926282008

Последний раз редактировалось Hugo121; 01.09.2012 в 01:31.
Hugo121 вне форума Ответить с цитированием
Старый 01.09.2012, 02:25   #18
doober
Старожил
 
Аватар для doober
 
Регистрация: 02.05.2009
Сообщений: 3,907
По умолчанию

Цитата:
Сообщение от Hugo121 Посмотреть сообщение
С SQL никто пока варианта не предложил, только упоминали - но я например не знаю, как можно сделать на SQL без лишнего открытия книг.
..
Если предложеный Игорем вариант не подойде,можно и SQL попробовать,но по скорости он проиграет словарю,я так думаю.
Я бы сделал так.
Отобрал книга-лист пары.
Далее запросом получил нужные данные и записал бы скорее всего в файл Access ,на крайний случай в CSV в таком формате.
Книга,лист, подопытный и остальные данные.
Если в Access ,то создать таблицу соответствий и вывести результат,но мороки много.Если файлы большие ,под 10-20 тыс строк,то есть смысл поиграться с этим вариантом
Анализ,обработка данных Недорого
doober вне форума Ответить с цитированием
Старый 03.09.2012, 09:18   #19
staniiislav
Форумчанин
 
Аватар для staniiislav
 
Регистрация: 16.04.2010
Сообщений: 695
По умолчанию

Цитата:
Сообщение от Hugo121 Посмотреть сообщение
Сделал то, что было интересно - как файлы открывать только один раз.
очень хорошее решение! думал как на sql это сделать, в принципе можно, но по скорости будет проигрывать, т.к. книг на открытие много...
Единственный способ стать умнее, играть с более умным противником...
staniiislav вне форума Ответить с цитированием
Старый 04.09.2012, 11:42   #20
Hugo121
Старожил
 
Регистрация: 11.05.2010
Сообщений: 5,170
По умолчанию

На словаре с коллекцией вроде попроще получается.
Схематично так:


Код:
Sub PereborFailov()
    Dim a, i&, t$, Dic As Object
    Dim el, col
    
    a = Range("C3", Cells(Rows.Count, "A").End(xlUp)).Value
    Set Dic = CreateObject("Scripting.Dictionary")
    With Dic
        .CompareMode = 1
        For i = 1 To UBound(a)
            t = a(i, 1)
            If Not .Exists(t) Then .Add t, New Collection
            .Item(t).Add a(i, 2) & "|" & a(i, 3) & "|" & i
        Next
    End With
    
    For Each el In Dic.keys
        Debug.Print "Открываем файл " & el
        For Each col In Dic.Item(el)
            Debug.Print "Ищем данные " & col
        Next
        Debug.Print "Закрываем файл " & el
    Next

End Sub
Или словарь в словаре:

Код:
Sub PereborFailov2() ' словарь в словаре
    Dim a, i&, t$, Dic As Object, Dic2 As Object
    Dim el, col
    
    a = Range("C3", Cells(Rows.Count, "A").End(xlUp)).Value
    Set Dic = CreateObject("Scripting.Dictionary")
    With Dic
        .CompareMode = 1
        For i = 1 To UBound(a)
            t = a(i, 1)
            If Not .exists(t) Then .Add t, CreateObject("Scripting.Dictionary")
            .Item(t).Item(a(i, 2) & "|" & a(i, 3) & "|" & i) = 0&
            
        Next
    End With
    
    For Each el In Dic.keys
        Debug.Print "Открываем файл " & el
        Set Dic2 = Dic.Item(el)
        For Each col In Dic2.keys
            Debug.Print "Ищем данные " & col '& "|" & Dic2.Item(col)
        Next
        Debug.Print "Закрываем файл " & el
    Next

End Sub
webmoney: E265281470651 Z422237915069 R418926282008

Последний раз редактировалось Hugo121; 04.09.2012 в 14:54.
Hugo121 вне форума Ответить с цитированием
Ответ


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



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Как скопировать лист в новую книгу m-1 Microsoft Office Excel 4 17.03.2011 18:26
VBA- как в коде перейти на другой лист Nasten'ka7 Microsoft Office Excel 11 01.02.2011 19:38
Копировать строку фильтрованного списка в другую книгу, на последнюю пустую строку Gvaridos Microsoft Office Excel 11 24.11.2010 00:48
найти и скопировать на другой лист нужные ячейки abcde Microsoft Office Excel 4 23.02.2010 07:46
Как скопировать выпадающий список на другой лист и в другую книгу gleod Microsoft Office Excel 4 07.07.2009 22:36