Страницы: 1 2 След.
RSS
[ Закрыто ] VBA Цикл(ы) в цикле(ах) и несколько (непростых) условий, массив или словарь? - чтобы "считать по-разному"
 
господа планетяне, мой креатив довёл меня до трёх макросов (с разных сторон одного вопроса)... и до отсутствия результатов... и наличия ошибок...
высказаться сложно - но нужен очень свежий взгляд - и я попробую - в надежде на ваши отзывчивые сердца... если вам хватит смелости не ругаться на 3 кода (вложенных) - знаю что много условий для каждого значения массива - это слишком напрягает сам макрос... но пролистать их своим зорким оком, чтобы хоть что-нибудь заработало...

по сути хочу сделать ювелирно кратко: (хотя ТЗ многомерное моё)...
в столбец N - разложить как в столбце U просчитано руками -
1) формулы разные для листов ..Р и ..С  (в 3-ем модуле я откомментировала логику ... на остальные меня не хватило)
2) при этом результаты надо закинуть в столбец N в зависимости от столбца K (если CAB или пусто - то ничего, если число, то считать по столбцу D и одной цифре (которую беру с листа ...С и кидаю на лист ..Р изначально, чтобы на листе всё было под рукой...)

прохожусь циклом по листам заданным (в оригинальном файле имею и др листы)...
и в зависимости от названия листа применяю ту (FUTSEAT-arr(столбца D)) для листа ..С или иную (arr(столбца D)-FUTSEAT) для листа ..Р формулу
... подглядывая на столбец К (условие - не участвует в расчёте, а см If IsNumeric)... иначе в новом массиве пустое значение ставлю...
при этом изначально SETT.PRICE нахожу на листе ..С и кидаю на ..Р (по евре ЕС.. и фунту ВР..)... но его ещё надо умножить на 1000 (это делаю потом) чтобы использовать в расчётах...

вобщем 3 варианта пыталась придумать... а проблемы то с With, то с Next. (может с чем ещё).. а может и с лексикой и с многоплановостью... уж больно много условий надо вложить др в др - может я что где недоглядела или не так сказала в макросе??  (хоть одном из них - чтобы хоть какой-нибудь заработал)... может ваш светлый взгляд, чистый ум и кристальная речь смогут дать жизнь хоть кому-нибудь из трёх вложенных??..

Заранее спасибо, если появится несколько минут, чтобы хотя бы прочитать в файле о чём я... sorry что много писанины там - но может там какая-нибудь небольшая ошибка, которую если поправить, то макрос (любой!) заработает??.. или почему циклы и условия сбоят и как их привести в порядок?
чтобы не гадать на кофейной гуще, кто вам отвечает и после этого не совершать кучу ошибок - обратитесь к собеседнику на ВЫ - ответ на ваш вопрос получите - а остальное вас не касается (п.п.п. на форумах)
 
Пока нет помощи, несколько надоедливых вопросов (модератор, сами понимаете, должность вредная и приставучая):
- три кода об одном и том же или есть желание несколько разных вопросов решить в одной теме?
- почти 70 кБ информации - так ли нужен такой объем для решения проблемы? 20-30 строчек мало? Вы ведь невольно заставляете помогающих тратить время на просмотр этих данных.
 
Каждая конструкция If ....... Then должна заканчиваться End If (у вас не так)
If shName = "BPC" Or shName = "ECC" Then
 
Цитата
Kuzmich пишет:
Каждая конструкция If ....... Then должна заканчиваться End If
Не совсем так. Прочитайте хотя бы справку. Если в блоке не предусматривается использование Else, то допускается запись в одну строку:
Код
If 1>0 Then Msgbox "Один больше нуля"


Так что код в файле рабочий, как я полагаю. Синтаксически, по крайней мере.
Даже самый простой вопрос можно превратить в огромную проблему. Достаточно не уметь формулировать вопросы...
 
Цитата
vikttur пишет: несколько надоедливых вопросов
1) 3 кода об одном и том же сейчас -2 попытки завернуть через массив и 1 попытка разглядеть и просчитать то что надо через словарь... надо чтобы заработал хоть один!.. господа светлые головы - чтобы у вас выбор был  :)   - в каком коде лучше понятна логика, тот и посмотрите please - может какие ремарки найдутся- комменты сделала только для 3-го... но по сути: (п3)
2) 70кБ - для максимальной реальности (кстати по большей половине нач данных удалила с листов) - листы с окончанием Р считаются по одной формуле, листы с окончанием ..С - по другой... цифра FUTSEAT(которая futures seattle price*1000) разная для листов ЕС и ВР... столбец-условие, чтобы узнать, что бросать/и надо ли/ - это options (call или put) seattle_bs - столбец К не от начала(а от шапки)... ребята я просто не расписываю, что откуда куда и ПОЧЕМУ - просто специфика формул и расчётов и файла такая - чтобы не усложнять просто просчитала формулой в последнем столбце, как надо считать, НО если в столбце К - слово САВ(пометила жёлтым) или пусто - то в столбце итогов - тоже оставлять пусто...
3) Таким образом... просмотреть можно первый лист: там в последнем столбце просчёты руками, которые надо посчитать без доп столбца макросом и результат выкинуть в столбец N, только надо при просчётах посматривать на столбец K (если он IsNumeric - то считать по формуле, если получается >0, то вставлять результат расчёта, если <0, то вставлять 0, а если столбец K НЕ IsNumeric, то вставлять пустое значение в N)... ну и для листов с окончанием ..P и ..С разный порядок расчётов (с точностью до наоборот по формуле) ... а для листов ЕС и ВР (указала в п2 - разная нач цифра, которая участвует в расчётах

просто выразила макросу много условий и завернула всё это в циклы (так пришлось)... а он ругается, то на Next, то на End With. то на If (может я Else неправильно синтаксисом выражаю)?... вобщем буду искать, 20-30 строчек не получилось - т к проблема тут, действительно, в общей картине и структуре... если найду то тоже отпишусь... как-то так ... а может там и условий и циклов то можно подсократить на VBA - не знаю- поэтому пришлось обратиться за помощью... но по логике условия как описала выше - однозначно такие - на VBA ищу способ правильно оформить... имхо...
Изменено: JeyCi - 20.06.2014 12:46:36
чтобы не гадать на кофейной гуще, кто вам отвечает и после этого не совершать кучу ошибок - обратитесь к собеседнику на ВЫ - ответ на ваш вопрос получите - а остальное вас не касается (п.п.п. на форумах)
 
Kuzmich , The_Prist - спасибо большое! что не испугались посмотреть на файл  :)   - respect  ... и за квалифицированные советы!.. буду искать загвоздку... только ещё одна неуверенность у меня есть - можно ли вот так прямым текстом использовать значения массива в формуле
Код
If ArrStr(j) > FUTSEAT * 1000 Then Arr(j) = ArrStr(j) - FUTSEAT * 1000 Else Arr(j) = 0
??
или из словаря брать в расчёты таким макаром:
Код
Else: If (FUTSEAT - .Item(a(i, 1))) < 0 Then c(i, 1) = 0
??

p.s.и нужно ли двоеточие после Else (vba сам поставил)...
иногда ругался на End If - поэтому и убрала там где ругался...
только ещё ругается на End With и на Next - в которые заворачиваю обработку листов...
(периодически пишет что нет начала цикла - как я только не пыталась зациклить... листы... нужны именно эти, в рабочем файле есть и другие)
Изменено: JeyCi - 20.06.2014 09:13:39
чтобы не гадать на кофейной гуще, кто вам отвечает и после этого не совершать кучу ошибок - обратитесь к собеседнику на ВЫ - ответ на ваш вопрос получите - а остальное вас не касается (п.п.п. на форумах)
 
Тоже глянул файл - аж два раза. Что нужно сделать - не понял, нужно вникать - что сложно  :)  
Но вот тут (где словарь):

Код
    With CreateObject("Scripting.Dictionary")
        'данные в массив
    With Sheets(shName)
        
        iLastrow = .Cells(FR.Rows.Count, 1).End(xlUp).Row
            a = .Range(FR.Offset(1, 0), FR.Offset(lr, 7)).Value

        'в словарь номера и "яблоки"
        For i = 1 To UBound(a)
            .Item(a(i, 1)) = a(i, 7)
        Next

 
как видите -
Код
.Item(a(i, 1)) 
берётся не у словаря, а у листа.
Вообще эту задачу я когда-то уже видел... И кажется фраза
Код
'в словарь номера и "яблоки"
моя?
 
Словарь работает без ошибок:

Скрытый текст
Но что именно делает, и правильно ли - не знаю..
 
Цитата
Hugo пишет: берётся не у словаря, а у листа.
Hugo ,   действительно, словарь всегда пытаюсь делать по вашим примерам (если надо)!...   обычно больше негде подсмотреть, кроме как на ваши светлые строки...
я вот и пыталась брать у листа (!) - а по словарю просто посмотреть a(i, 7) - если он IsNumeric...  то брать для расчёта a(i, 1)) - или его отнимать от FUTSEAT (для листов ..С), или FUTSEAT отнимать от него (для листов ..Р)...  FUTSEAT - это фиолетовое число в файле *1000 ... для листов ВР.. и ЕС.. - оно разное... на листе ЕСС не фиолетовое, но тоже на ячейку вниз от SETT.PRICE, который нахожу методом Find... имхо...
p.s. их сначала просто перекидываю на соотв. лист ..Р, чтобы потом взять в расчёты на листе (умножив на 1000)... ну, и всё в цикл(ы) и с условиями
Изменено: JeyCi - 20.06.2014 21:49:46
чтобы не гадать на кофейной гуще, кто вам отвечает и после этого не совершать кучу ошибок - обратитесь к собеседнику на ВЫ - ответ на ваш вопрос получите - а остальное вас не касается (п.п.п. на форумах)
 
Условия надо писать так:
было
Код
If shName = "BPP" Or "ECP" Then Arr(i, 1) = ArrStr(j, 1) - FUTSEAT
                    Else: If shName = "BPC" Or "ECC" Then Arr(i, 1) = 0
End If 
надо
Код
If shName = "BPP" Or "ECP" Then 
    Arr(i, 1) = ArrStr(j, 1) - FUTSEAT
ElseIf shName = "BPC" Or "ECC" Then 
    Arr(i, 1) = 0
End If 
Excel + SQL = Activetables
 
А не так ли нужно:

Код
If shName = "BPP" Or shName = "ECP" Then  
я так в коде исправил - но он правда вообще до этих проверок не доходит, т.к вот тут ничего не находится:

Код
Set Rng = Range("K1:K20")
        Set FR = Rng.Find("SETTLE_bs") 
далее не вникал, некогда...
Изменено: Hugo - 20.06.2014 10:11:15
 
Цитата
Hugo пишет: Словарь работает без ошибок: Но что именно делает, и правильно ли - не знаю..
так ничего не даёт, но хоть без ошибок работает!... надо в столбце N раскинуть цифры как в столбце(последнем) ITM (ну с учётом условий-надо ли выводить и что)... загвоздка в цикле видимо... после такого With CreateObject("Scripting.Dictionary") обязательно цикл по листу указать?... или можно ДО ЭТОГО цикл по листу указать?.. или 2 раза (цикл в цикле)?  :(    или 3 раза (цикл в цикле)?  

Код
For n = 0 To UBound(ArrSh) 
shName = ArrSh(i)
With Sheets(shName)   '???????????????
...
With CreateObject("Scripting.Dictionary")
          ' With Sheets(shName)  '??????????????????????
           iLastrow = .Cells(FR.Rows.Count, 1).End(xlUp).Row
           a = .Range(FR.Offset(1, 0), FR.Offset(lr, 7)).Value
...
End With
Изменено: JeyCi - 20.06.2014 10:31:44
чтобы не гадать на кофейной гуще, кто вам отвечает и после этого не совершать кучу ошибок - обратитесь к собеседнику на ВЫ - ответ на ваш вопрос получите - а остальное вас не касается (п.п.п. на форумах)
 
Цитата
PowerBoy пишет: надо
простите, где?  :oops:  ...(в каком из модулей?)... с ходу не совсем нахожу
Изменено: JeyCi - 20.06.2014 10:22:42
чтобы не гадать на кофейной гуще, кто вам отвечает и после этого не совершать кучу ошибок - обратитесь к собеседнику на ВЫ - ответ на ваш вопрос получите - а остальное вас не касается (п.п.п. на форумах)
 
Цитата
Hugo пишет: он правда вообще до этих проверок не доходит
упс, одной буквы не хватает... SEATTLE_bs... sorry

Код
Set Rng = Range("K1:K20")
     Set FR = Rng.Find("SEATTLE_bs")
чтобы не гадать на кофейной гуще, кто вам отвечает и после этого не совершать кучу ошибок - обратитесь к собеседнику на ВЫ - ответ на ваш вопрос получите - а остальное вас не касается (п.п.п. на форумах)
 
Цитата
JeyCi пишет:
простите, где?
Module3
Excel + SQL = Activetables
 
Вариант словаря - уже что-то выводит:
Скрытый текст
 
Цитата
PowerBoy пишет: Module3
постаралась подправить (см вложение) по логике своих расчётов - по вашему совету "как надо" (всегда спасибо за дельный совет!)...
но он (макрос) End With говорит что without With - всё та же проблема с циклом по листам... имхо... вложу
Изменено: JeyCi - 20.06.2014 14:36:01
чтобы не гадать на кофейной гуще, кто вам отвечает и после этого не совершать кучу ошибок - обратитесь к собеседнику на ВЫ - ответ на ваш вопрос получите - а остальное вас не касается (п.п.п. на форумах)
 
Все Ваши ошибки из-за плохого форматирования текста кода. Выравнивайте условия и циклы и все будет хорошо видно.

Код
If Not FR Is Nothing Then
 
Вот у этой конструкции везде нету закрывающего Endif
Excel + SQL = Activetables
 
Цитата
Hugo пишет: 'в словарь номера и "яблоки"
Код
                For i = 1 To UBound(a)
                    .Item(a(i, 1)) = a(i, 7)
                Next

1) да кстати подправлю свой комментарий (мои номера и яблоки):
' в словарь seattle опционов (столбец К) - чтобы знать "считать, 0 или пусто ставить" и страйки  (столбец D) - которые в формулу(ы)
2) добавила в Dim FUT As Range... видимо когда-то по ошибке удалила(когда правила код)...
3) в формулах везде добавила: умножение FUTSEAT на 1000... хотя можно и когда задаём FUTSEAT= это сделать(*1000)... кажется, что он у меня именно это и  не понимает... поэтому и считает не совсем то

p.s. что-то странное пока что в результатах... покручу код
Изменено: JeyCi - 20.06.2014 15:55:43
чтобы не гадать на кофейной гуще, кто вам отвечает и после этого не совершать кучу ошибок - обратитесь к собеседнику на ВЫ - ответ на ваш вопрос получите - а остальное вас не касается (п.п.п. на форумах)
 
Цитата
PowerBoy пишет: Все Ваши ошибки из-за плохого форматирования текста кода. Выравнивайте условия и циклы и все будет хорошо видно... у этой конструкции везде нету закрывающего Endif
я кстати это и попыталась сделать в новом вложенном файле... (для модуля 3)
а про End If - я почему-то верю в пост №4... если у меня проблема с End With... имхо... но на всякий случай поставила - в конце...
может я размерность массивов неверно задала там как-то? в циклах For k = 1 To UBound(ArrSeat) и им подобных, чисто синтаксически?... или где ещё?.. и он(макрос) путается...

!! упс... перевложила файл с модулем3 в пост №17... ArrSeat- через k, ArrStr- через j, Arr через i
ошибок вроде не выдаёт, но результата тоже не выдаёт...
Изменено: JeyCi - 20.06.2014 14:34:28
чтобы не гадать на кофейной гуще, кто вам отвечает и после этого не совершать кучу ошибок - обратитесь к собеседнику на ВЫ - ответ на ваш вопрос получите - а остальное вас не касается (п.п.п. на форумах)
 
да..., видимо, с номерами и яблоками я погорячилась... номера - совсем не номера, а яблоки в моих проблемах не причём, похоже... можно бы напрячься поискать ключи для большей убедительности макросу, чтобы брал именно то, что надо... но, кажется мне, что не поможет это макросу... подход словарей тут видимо не пройдёт

подход массивов остаётся, после всех внесённых подсказок... проблемой кажется число FUTSEAT, которое пытаюсь задать, а макрос не понимает и никак не считает, возможно...

Код
If shName = "BPC" Or shName = "ECC" Then
      Set FUT = .Range("K1:K10").Find("SETT.PRICE")
      FUTSEAT = FUT.Offset(1, 0).Value * 1000     'если лист ..С задаём FUTSEAT*1000 число которое подставляется далее в формулу   
    ElseIf shName = "BPP" Or shName = "ECP" Then
      FUTSEAT = .[K1].Value * 1000            'если лист ..Р задаём FUTSEAT*1000 число которое подставляется далее в формулу
End If

(FUTSEAT As Long изначально)... правильно ли так сказать кодом??.. чтобы потом использовать FUTSEAT в формулах типа

Код
Arr(i, 1) = ArrStr(j, 1) - FUTSEAT

или на 1000 умножать в самой формуле?
или надо set FUTSEAT = .[K1].Value * 1000?
чтобы уж точно увидев результат, поверить что мы циклы правильно расставили... ??
Изменено: JeyCi - 20.06.2014 20:02:00
чтобы не гадать на кофейной гуще, кто вам отвечает и после этого не совершать кучу ошибок - обратитесь к собеседнику на ВЫ - ответ на ваш вопрос получите - а остальное вас не касается (п.п.п. на форумах)
 
JeyCi
В модуле3     .Range(FR.Offset(1, -7), FR.Offset(lr, -7)).Value = ArrStr 'массив страйков D столбец
                     .Range(FR.Offset(1, 0), FR.Offset(lr, 0)).Value = ArrSeat 'массив условие K столбец (значения CAB или Not IsNumeric - будут в новом массиве пустыми значениями)
не определена переменная lr и , как мне кажется, должна быть точка перед Range
 
вот пробую вот так
Код
lr = Cells(FR.Rows.Count, FR.Column).End(xlUp).Row  '??????
      .Range(FR.Offset(1, -7), FR.Offset(lr, -7)).Value = ArrStr  
      .Range(FR.Offset(1, 0), FR.Offset(lr, 0)).Value = ArrSeat   
      
      ReDim Arr(1 To UBound(ArrSeat), 1 To 1)       ' ошибка Type mismatch

Redim - ' ошибка Type mismatch...
a lr - так правильно задать? помню я задавали мы как-то lastColumn  :)
чтобы не гадать на кофейной гуще, кто вам отвечает и после этого не совершать кучу ошибок - обратитесь к собеседнику на ВЫ - ответ на ваш вопрос получите - а остальное вас не касается (п.п.п. на форумах)
 
Цитата
JeyCi пишет:
чтобы не гадать на кофейной гуще,
 
Цитата
lr = Cells(FR.Rows.Count, FR.Column).End(xlUp).Row  '??????
JeyCi, Вы лучше напишите словами, какую строку вы хотите найти этим выражением?
Может вам нужна последняя строка в столбце К
iLastrow = .Cells(Rows.Count, 11).End(xlUp).Row
И еще вопрос:
Если вы делаете цикл по листам
Код
For n = 0 To UBound(ArrSh) 'запускаем цикл по листам
    shName = ArrSh(i)
With Sheets(shName) 
то зачем внутри этого цикла идет проверка
Код
            If shName = "BPP" Or shName = "ECP" Then
 
Цитата
Kuzmich пишет: то зачем внутри этого цикла идет проверка
потому что в зависимости от названия листа - выбирается 1 из 2х формул (что от чего отнимается- (FUTSEAT от STRIKE) или (STRIKE от FUTSEAT)
Цитата
Kuzmich пишет: Может вам нужна последняя строка в столбце К
последняя из К или из D (по сути она одна), но все массивы будут браться от шапки, а не от 1-ой... напомнило мне это ту ситуацию (из знакомого вам макроса)
Изменено: JeyCi - 20.06.2014 23:29:47
чтобы не гадать на кофейной гуще, кто вам отвечает и после этого не совершать кучу ошибок - обратитесь к собеседнику на ВЫ - ответ на ваш вопрос получите - а остальное вас не касается (п.п.п. на форумах)
 
Цитата
массивы будут браться от шапки
iLastrow = .Cells(Rows.Count, 11).End(xlUp).Row
ArrStr = .Range(FR.Offset(1, -7), FR.Offset(iLastrow - FR.Row, -7)).Value 'массив страйков D столбец
ArrSeat = .Range(FR.Offset(1, 0), FR.Offset(iLastrow - FR.Row, 0)).Value 'массив условие K столбец (значения CAB или Not IsNumeric - будут в новом массиве пустыми значениями)
 
Вы задаете новый массив

Код
            ReDim Arr(1 To UBound(ArrSeat), 1 To 1) 'задаём массив выгрузки, куда просчитываем по формулам ниже (и с учётом столбца-условий по-разному для листов ..С и ..Р) ...........

 
но дальше у вас нет задания начального значения i=1 и изменения этого параметра для Arr(i,1) при заполнении массива
 
Цитата
Kuzmich пишет: но дальше у вас нет задания начального значения i=1 и изменения этого параметра для Arr(i,1) при заполнении массива
но ведь массив заполняется значениями просчитанными по формуле... многовато условий, но Arr(i,1) задаётся... т е надо ещё как-то обернуть это всё в счётчик For i=1 To Ubound(Arr)... Next i ?? ... а ведь идея-то ваша - ооочень справедливое замечание  :!:  
теперь хоть я правильно вкладываю все условия в условия обернув правильными строчками и синтаксисом? ... правильно ли я мыслю в этом куске? (под спойлером)... подправила

Скрытый текст
Изменено: JeyCi - 21.06.2014 10:25:42
чтобы не гадать на кофейной гуще, кто вам отвечает и после этого не совершать кучу ошибок - обратитесь к собеседнику на ВЫ - ответ на ваш вопрос получите - а остальное вас не касается (п.п.п. на форумах)
 
В формулах для столбца ITM вы проверяете =ЕСЛИ(ЕЧИСЛО(D84);ЕСЛИ(($K$4*1000-D84)>0;$K$4*1000-D84;0);"")
столбец D на число, а в макросе проверяете столбец К. Где правда?
Все три массива ArrStr, ArrSeat и Arr у вас имеют одинаковую размерность, поэтому,
я думаю, не надо циклов по i, j и k, достаточно одного.
Исправьте выгрузку
FR.Offset(1, 3).Resize(UBound(Arr)) = Arr 'выгружаем массив (ITM) полученный в столбец N (от слова "EXERCISE")
Страницы: 1 2 След.
Читают тему
Наверх