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

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

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

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

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

Ответ
 
Опции темы Поиск в этой теме
Старый 23.09.2011, 14:17   #11
Dexter_M
Пользователь
 
Регистрация: 13.09.2011
Сообщений: 29
По умолчанию

Изменил код:
Код:

Sub prob_my()

    Dim a, b(), c(), oDict As Object, i&, ii&, iii&, uu$, u$, temp$, x&, sep_$, xx$, yr1$

    a = Split(CreateObject("Scripting.FileSystemObject").OpenTextFile("C:\Documents and Settings\Ãîíñàëåñ\Ðàáî÷èé ñòîë\ýêñòðèì\äèñïåðñèÿ\SCH7FF11.txt", 1).ReadAll, vbNewLine)
    sep_ = Mid$(1 / 2, 2, 1)

    'Dim tm: tm = Timer
    ReDim b(1 To UBound(a, 1), 1 To 7)
    ReDim c(1 To UBound(a, 1), 1 To 11)
 
    
    Set oDict = CreateObject("Scripting.Dictionary")
    oDict.CompareMode = 1
    For i = 0 To UBound(a)
        If Len(Trim(a(i))) Then
            aa = Split(Replace(a(i), ".", sep_), ";")
            If Len(Trim(aa(7))) Then
                temp = aa(0) & "|" & aa(2) & "|" & aa(3) & "|" & aa(1)
                  If Not oDict.Exists(temp) Then
                    ii = ii + 1
                    b(ii, 1) = aa(0):  b(ii, 3) = aa(2): b(ii, 4) = aa(3): b(ii, 2) = aa(1)
                     b(ii, 7) = --aa(7) ': b(ii, 5) = --aa(7): b(ii, 6) = 1
                    oDict.Add temp, CStr(ii)
                
                End If
                
                If b(ii, 2) < 1979 And b(ii, 2) > 1948 Then
                yr1 = aa(0) & "|" & aa(2) & "|" & aa(3)
                    If Not oDict.Exists(yr1) Then
                    iii = iii + 1
                       c(iii, 1) = aa(0):  c(iii, 2) = aa(2): c(iii, 3) = aa(3): c(iii, 4) = "1949-1978"
                      c(iii, 5) = --aa(7): c(iii, 6) = 1: c(iii, 7) = --aa(7)
                      oDict.Add yr1, CStr(iii)
                    Else
                        xx = oDict.Item(yr1)
                        c(xx, 5) = c(xx, 5) + aa(7): c(xx, 6) = c(xx, 6) + 1: c(xx, 7) = c(xx, 5) / c(xx, 6)
      
                   End If
                 ElseIf b(ii, 2) < 2009 And b(ii, 2) > 1978 Then
                yr1 = aa(0) & "|" & aa(2) & "|" & aa(3)
                    If Not oDict.Exists(yr1) Then
                    iii = iii + 1
                       c(iii, 8) = "1979-2008"
                      c(iii, 9) = --aa(7): c(iii, 10) = 1: c(iii, 11) = --aa(7)
                      oDict.Add yr1, CStr(iii)
                    Else
                        xx = oDict.Item(yr1)
                        c(xx, 9) = c(xx, 9) + aa(7): c(xx, 10) = c(xx, 10) + 1: c(xx, 11) = c(xx, 9) / c(xx, 10)
                    End If
                 End If
            End If
        End If
    Next
    
    
    
    On Error Resume Next    'åñëè âäðóã ii=0
    With Workbooks.Add.Worksheets(1)
        .Range("A1:M1") = Split("index mm dd ïåðèîä Tsum count Tmid ïåðèîä Tsum count Tmid")
        .Columns(1).NumberFormat = "@"
        .Range("A2:M2").Resize(iii) = c
    End With
    On Error GoTo 0
    'Debug.Print Timer - tm

End Sub
выдает ошибку Type mismatch
Если убрать вот эту часть:
Код:

                ElseIf b(ii, 2) < 2009 And b(ii, 2) > 1978 Then
                yr1 = aa(0) & "|" & aa(2) & "|" & aa(3)
                    If Not oDict.Exists(yr1) Then
                    iii = iii + 1
                       c(iii, 8) = "1979-2008"
                      c(iii, 9) = --aa(7): c(iii, 10) = 1: c(iii, 11) = --aa(7)
                      oDict.Add yr1, CStr(iii)
                    Else
                        xx = oDict.Item(yr1)
                        c(xx, 9) = c(xx, 9) + aa(7): c(xx, 10) = c(xx, 10) + 1: c(xx, 11) = c(xx, 9) / c(xx, 10)
                    End If
то все работает...
Как побороть???
Dexter_M вне форума Ответить с цитированием
Старый 23.09.2011, 15:14   #12
Hugo121
Старожил
 
Регистрация: 11.05.2010
Сообщений: 5,170
По умолчанию

В b(ii, 2) - строка.
Попробуйте при занесении сразу преобразовать в число:
b(ii, 2) = --aa(1)
Не удивили эти два минуса в моём коде?
Глубже алгоритм не анализировал
webmoney: E265281470651 Z422237915069 R418926282008
Hugo121 вне форума Ответить с цитированием
Старый 23.09.2011, 16:57   #13
Dexter_M
Пользователь
 
Регистрация: 13.09.2011
Сообщений: 29
По умолчанию

Цитата:
Сообщение от Hugo121 Посмотреть сообщение
В b(ii, 2) - строка.
Попробуйте при занесении сразу преобразовать в число:
b(ii, 2) = --aa(1)
Не удивили эти два минуса в моём коде?
Глубже алгоритм не анализировал
Сделал, но результат тот же.
Dexter_M вне форума Ответить с цитированием
Старый 23.09.2011, 17:05   #14
Hugo121
Старожил
 
Регистрация: 11.05.2010
Сообщений: 5,170
По умолчанию

Вечером дома гляну на примере. Наверное ещё где-то типы не совпадают.
Можете ещё дополнительно кусок текста с разными годами показать, чтоб было на чём тестить? Лениво в том править...
webmoney: E265281470651 Z422237915069 R418926282008
Hugo121 вне форума Ответить с цитированием
Старый 23.09.2011, 17:46   #15
Dexter_M
Пользователь
 
Регистрация: 13.09.2011
Сообщений: 29
По умолчанию

да, конечно.
Вряд ли типы несовпадают, т.к. если по отдельности вставлять части
Код:
 If b(ii, 2) < 1979 And b(ii, 2) > 1948 Then
                yr1 = aa(0) & "|" & aa(2) & "|" & aa(3)
                    If Not oDict.Exists(yr1) Then
                    iii = iii + 1
                       c(iii, 1) = aa(0):  c(iii, 2) = aa(2): c(iii, 3) = aa(3): c(iii, 4) = "1949-1978"
                      c(iii, 5) = --aa(7): c(iii, 6) = 1: c(iii, 7) = --aa(7)
                      oDict.Add yr1, CStr(iii)
                    Else
                        xx = oDict.Item(yr1)
                        c(xx, 5) = c(xx, 5) + aa(7): c(xx, 6) = c(xx, 6) + 1: c(xx, 7) = c(xx, 5) / c(xx, 6)
      
                   End If
и
Код:
 ElseIf b(ii, 2) < 2009 And b(ii, 2) > 1978 Then
                yr1 = aa(0) & "|" & aa(2) & "|" & aa(3)
                    If Not oDict.Exists(yr1) Then
                    iii = iii + 1
                       c(iii, 8) = "1979-2008"
                      c(iii, 9) = --aa(7): c(iii, 10) = 1: c(iii, 11) = --aa(7)
                      oDict.Add yr1, CStr(iii)
                    Else
                        xx = oDict.Item(yr1)
                        c(xx, 9) = c(xx, 9) + aa(7): c(xx, 10) = c(xx, 10) + 1: c(xx, 11) = c(xx, 9) / c(xx, 10)
                    End If
то все работает, а если обе, то выдает ошибку...
Вложения
Тип файла: rar SCH7FF11.rar (192.0 Кб, 9 просмотров)
Dexter_M вне форума Ответить с цитированием
Старый 23.09.2011, 17:55   #16
Hugo121
Старожил
 
Регистрация: 11.05.2010
Сообщений: 5,170
По умолчанию

Посмотрел уже - в c(xx, 9) у Вас два значения температуры сразу, поэтому они не делятся на c(xx, 10).
А получается так потому, что в строке
c(xx, 9) = c(xx, 9) + aa(7)
прибавляете к строке строку.
А получается так потому, что такое значение уже есть в словаре - оно туда попадает при проверке на b(ii, 2) < 1979 And b(ii, 2) > 1948
В общем, нужно алгоритм править.
Может быть два словаря завести? Или Вам нужно строго параллельно рядом выгружать?
Я правда в деталях код не понял...
Но предлагаю сделать два словаря и два массива (для каждого диапазона свой) и затем выгрузить их просто рядом на лист.
Или как уникальное брать склейку идентификатора группы (придумать одну на группу) и как было. Тогда должно заработать. Наверное...
webmoney: E265281470651 Z422237915069 R418926282008

Последний раз редактировалось Hugo121; 23.09.2011 в 18:09.
Hugo121 вне форума Ответить с цитированием
Старый 23.09.2011, 18:16   #17
Hugo121
Старожил
 
Регистрация: 11.05.2010
Сообщений: 5,170
По умолчанию

Да, заработало:
в первом сравнении
yr1 = "1|" & aa(0) & "|" & aa(2) & "|" & aa(3)
во втором
yr1 = "2|" & aa(0) & "|" & aa(2) & "|" & aa(3)

Ну и выгрузку нужно подправить:
With Workbooks.Add.Worksheets(1)
.Range("A1:K1") = Split("index mm dd ia?eia Tsum count Tmid ia?eia Tsum count Tmid")
.Columns(1).NumberFormat = "@"
.Range("A2:K2").Resize(iii) = c
End With
Только заголовки чуть изменить - кодировка поползла.

Хотя всёж нужно два массива - данные ведь не рядом выгружаются, значит можно сделать два массива, и выгружать рядом, или на разные листы, или строго один под другим, как угодно.

И кстати можно ускориться (сократить количество проверок), если изменить код типа так:

Код:
If b(ii, 2) < 1979 Then
If b(ii, 2) > 1948 Then
...
...
End If
End If
webmoney: E265281470651 Z422237915069 R418926282008

Последний раз редактировалось Hugo121; 23.09.2011 в 18:25.
Hugo121 вне форума Ответить с цитированием
Старый 23.09.2011, 19:31   #18
Dexter_M
Пользователь
 
Регистрация: 13.09.2011
Сообщений: 29
По умолчанию

Цитата:
Сообщение от Hugo121 Посмотреть сообщение
Хотя всёж нужно два массива - данные ведь не рядом выгружаются, значит можно сделать два массива, и выгружать рядом, или на разные листы, или строго один под другим, как угодно.
Да, все получилось! Загрузил данные в разные массивы, c и d.
На сколько я понял, то массив получается размерностью (iii, 7)
Но возник еще вопрос:
хочу еще поработать с этими файлами, а именно добавить обработку и создание нового массива:
Код:
 For ii = LBound(b) To UBound(b)
    For iii = LBound(c) To UBound(c)
    For uu = LBound(d) To UBound(d)

         If b(ii, 2) < 1979 And b(ii, 2) > 1948 Then
  
                If b(ii, 3) = c(iii, 2) Then
                    u = u + 1
                    e(u, 1) = (b(ii, 7) - c(iii, 7)) ^ 2
                End If
        End If

        If b(ii, 2) < 2009 And b(ii, 2) > 1978 Then
  
                If b(ii, 3) = d(uu, 2) Then
                    u = u + 1
                    e(u, 1) = (b(ii, 7) - d(uu, 7)) ^ 2
                End If
        End If

    Next
    Next
    Next
но пишет опять "type mismatch".
С чем это связано и как можно исправить?
Dexter_M вне форума Ответить с цитированием
Старый 23.09.2011, 20:28   #19
Hugo121
Старожил
 
Регистрация: 11.05.2010
Сообщений: 5,170
По умолчанию

Не вникая (ибо нужен рабочий пример с обоими файлами) - посмотрите, что хранится в b(ii, 7) и c(iii, 7). Тут должны быть числа, а не строки. Просто при ошибке наведите мышь и увидите. Ну или в окне Locals можно всё изучить.
Из текста Вы получаете строку, и её нужно перед помещением в массив преобразовать в числа - те числа, которые будете считать. Остальные данные можно не преобразовывать.
webmoney: E265281470651 Z422237915069 R418926282008
Hugo121 вне форума Ответить с цитированием
Старый 26.09.2011, 09:45   #20
Dexter_M
Пользователь
 
Регистрация: 13.09.2011
Сообщений: 29
По умолчанию

Все получилось!
Ув. Hugo121, спасибо Вам огромное!!!

А не подскажите, в чем ошибка в следующем коде:
Код:
For iii = LBound(c) To UBound(c)
For ii = LBound(b) To UBound(b)
                   
    If b(ii, 3) = c(iii, 2) And b(ii, 4) = c(iii, 3) Then
           u = u + 1
           e(u, 1) = (b(ii, 7) - c(iii, 7))
     End If
           
Next
Next
Суть в том, что У b() и c() разное количество строк, а необходимо, что бы для каждого совпадающего дня и месяца в этих массивах производилась операция вычитания соответствующих данных.
Dexter_M вне форума Ответить с цитированием
Ответ


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



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Дан динамический массив строк, вывести все слова начинающиеся с большой буквы C++ builder Memphi[s] Помощь студентам 0 02.03.2011 16:34
Большой объем данных matanga Microsoft Office Excel 4 09.12.2010 13:14
SQL - обьединение и управление несколькими базами данных MarinN SQL, базы данных 1 08.11.2010 10:09
Как виделить большой кусок памяти под массив? Tania Мультимедиа в Delphi 7 23.04.2010 01:53
Поиск min/max данных с несколькими условиями - нужна помощь! /nort/ Microsoft Office Excel 3 16.03.2008 00:13