Выбрать дату в календареВыбрать дату в календаре

Страницы: 1
VBA динамически скрыть/показать вкладки на ленте (Ribbon)
 
Добрый день.

Поиск (см. сабж) мне вывел под сотню результаов, но все не о том. Прошу ткнуть носом в правильную тему.
Задача: есть надстройка (AddIn), которая содержи две вкладки на Риббоне. Нужно, чтобы при переключении с книги на книгу (событие Application WorkbookActivate или еще что-то), одна из вкладок показывалась, а другая скрывалась. Вкладки, естествено, оформлены через <tab id="premiere_01"...  т.д.
Изменено: skogkatt - 08.08.2019 18:11:13
VBA разные методы автофильтра по дате - работает для ">=", но не работает для "=" (и наоборот)
 
Цель: использовать одну и ту же функцию для установки автофильтра по дате (в дальнейшем это должен быть метод класса).

На форуме тема "АФ по дате" поднималась неоднократно (поиск пролопачен), но вот с какой проблемой я столкнулся. Самый популярный совет - при установке фильтра преобразовывать дату в формат даты США, т.е. "m/d/yyyy" - в моем случае работает только с операторами сравнения больше/меньше, но не работает с оператором "="! Два других рекомендованных метода - преобразовывать дату через Format(varDate, "Short Date") или через CStr(varDate). Но с ними тоже фокусы: во-первых, они как раз НЕ работают на операторах сравнения, отличных от "=", а во-вторых, они НЕ работают на формате даты, отличном от "Short Date". Чтобы разобраться окончательно, соорудил испытательный файл (приложен). В нем две одинаковых таблицы, одна с датой в коротком формате, другая с длинным форматом даты. Функция Sub FilterEqualOrMore запускает последовательно автофильтр ">=" на обоих таблицах по всем трем методам (DateToUS, "Short Date", Cstr(), после каждого запуска Stop для просмотра результата). Функция Sub FilterEqual делает тоже самое, но автофильтр по "=".

Резюме:
1) DateToUS - работает на ">=", не работает на "=" (верно для обоих форматов даты)
2) "Short Date" и CStr()  не работают на ">=", работает на "=" (но только на таблице с датой в кратком формате)

Вопрос знатокам: (1) может быть, я что-то упустил, и DateToUS() при некотором шаманстве все же будет работать на сравнение "="?
(2) Может быть, есть другой способ унификации такого автофильтра?
(3) Как все-таки быть, если формат даты отличен от "краткого" (см. Трюк ниже)?

PS Естественно, что возможны два варианта "обмануть Excel":
(1) функция SetDateFilter, выставляющая фильтр, просто будет подставлять разные преобразования в зависимости от оператора сравнения ("Short Date" для "равно", DateToUS для других). Но это все равно не будет работать на других форматах даты, кроме краткого.
(2)  ТРЮК: Пользоваться DateToUS, а если встретится оператор "=", заменять его на двойной, ">=" AND "<=". Работает (см. файл примера), причем на всех форматах даты (проверено), но... (а) так мы не сможем выставить фильтр на НЕСКОЛЬКО несвязанных дат (а хотелось бы для полноты, иногда надо бывает), (б) кто знает, где еще будет подложена свинья? Хотелось бы универсального метода.
Код
Public Function DateToUS(ByVal dDate As Date) As String
    DateToUS = Format(dDate, "m""/""d""/""yyyy") ' "mm/dd/yyyy"
End Function

Public Function AFShowAll(ws As Excel.Worksheet)
    On Error Resume Next ' if all data is shown, an error will be raised
    ws.ShowAllData
    On Error GoTo 0
End Function

Public Sub FilterEqualOrMore()
Dim tRange As Excel.Range, tRange2 As Excel.Range, dDate As Date

    dDate = CDate("24.07.2019")

    Set tRange = Application.Worksheets("Таблица").Range("Таблица")
    Set tRange2 = Application.Worksheets("Таблица (2)").Range("Таблица2")

    ' via DateToUs
    SetDateFilter tRange, 1, dDate, ">="
    SetDateFilter tRange2, 1, dDate, ">="
    Stop

    ' via "Short Date" format
    SetDateFilter2 tRange, 1, dDate, ">="
    SetDateFilter2 tRange2, 1, dDate, ">="
    Stop

    ' via CStr conversion
    SetDateFilter3 tRange, 1, dDate, ">="
    SetDateFilter3 tRange2, 1, dDate, ">="
    Stop

    ' via CLng conversion
    SetDateFilterCLNG tRange, 1, dDate, ">="
    SetDateFilterCLNG tRange2, 1, dDate, ">="
    Stop

     ' via CDbl conversion
    SetDateFilterCDBL tRange, 1, dDate, ">="
    SetDateFilterCDBL tRange2, 1, dDate, ">="

End Sub

Public Sub FilterEqual()
Dim tRange As Excel.Range, tRange2 As Excel.Range, dDate As Date

    dDate = CDate("24.07.2019")

    Set tRange = Application.Worksheets("Таблица").Range("Таблица")
    Set tRange2 = Application.Worksheets("Таблица (2)").Range("Таблица2")

    ' via DateToUs
    SetDateFilter tRange, 1, dDate, "="
    SetDateFilter tRange2, 1, dDate, "="
    Stop
    
    ' via "Short Date" format
    SetDateFilter2 tRange, 1, dDate, "="
    SetDateFilter2 tRange2, 1, dDate, "="
    Stop
    
    ' via CStr conversion
    SetDateFilter3 tRange, 1, dDate, "="
    SetDateFilter3 tRange2, 1, dDate, "="
    Stop

    ' via CLng conversion
    SetDateFilterCLNG tRange, 1, dDate, "="
    SetDateFilterCLNG tRange2, 1, dDate, "="
    Stop
    
     ' via CDbl conversion
    SetDateFilterCDBL tRange, 1, dDate, "="
    SetDateFilterCDBL tRange2, 1, dDate, "="
    Stop
   
   'via the CraftyGimmick
    SetDateFilterEqual_HitroTryuk tRange, 1, dDate
    SetDateFilterEqual_HitroTryuk tRange2, 1, dDate
    
    
End Sub

Public Function SetDateFilter(tabRange As Excel.Range, ByVal lCol As Long, ByVal dDate As Date, _
                              Optional ByVal sCriteria As String = "=")
' works via DateToUS conversion
    AFShowAll tabRange.Worksheet
    tabRange.AutoFilter lCol, sCriteria & DateToUS(dDate)
End Function

Public Function SetDateFilter2(tabRange As Excel.Range, ByVal lCol As Long, ByVal dDate As Date, _
                              Optional ByVal sCriteria As String = "=")
' via Format("Short Date") conversion
    AFShowAll tabRange.Worksheet
    tabRange.AutoFilter lCol, sCriteria & Format(dDate, "Short Date")
End Function

Public Function SetDateFilter3(tabRange As Excel.Range, ByVal lCol As Long, ByVal dDate As Date, _
                              Optional ByVal sCriteria As String = "=")
' works via Cstr() conversion
    AFShowAll tabRange.Worksheet
    tabRange.AutoFilter lCol, sCriteria & CStr(dDate)
End Function

Public Function SetDateFilterCLNG(tabRange As Excel.Range, ByVal lCol As Long, ByVal dDate As Date, _
                              Optional ByVal sCriteria As String = "=")
' works via CLng() conversion
    AFShowAll tabRange.Worksheet
    tabRange.AutoFilter lCol, sCriteria & CLng(dDate)
End Function

Public Function SetDateFilterCDBL(tabRange As Excel.Range, ByVal lCol As Long, ByVal dDate As Date, _
                              Optional ByVal sCriteria As String = "=")
' works via CLng() conversion
    AFShowAll tabRange.Worksheet
    tabRange.AutoFilter lCol, sCriteria & CDbl(dDate)
End Function


Public Function SetDateFilterEqual_HitroTryuk(tabRange As Excel.Range, ByVal lCol As Long, ByVal dDate As Date)
' via the CraftyGimmick
    AFShowAll tabRange.Worksheet
    tabRange.AutoFilter lCol, ">=" & DateToUS(dDate), xlAnd, "<=" & DateToUS(dDate)
End Function


Изменено: skogkatt - 02.08.2019 12:19:36 (опять исправлена ошибка вставки кириллических строк)
Найти значения родительских PivotItem выделенной ячейки
 
Добрый день, коллеги.

Дано: выделена ячейка сводной таблицы. Причем неважно, в области строк, столбцов или значений. Ну, пусть к примеру в области значений.
Нужно: получить список всех пар "поле - значение" сводной таблицы, которые относятся к этой ячейке.
Зачем: хитрая навигация по подсобным листам, облегчающая жизнь пользователю. Например, нажимает он кнопку "данные по заказу", находясь где-то в таблице распределения заказов по датам и станкам, и переходит на соответствующий лист.

Как это виделось бы в идеале:
К примеру, хочу узнать значение в "родительском" поле "Код заказа" (см. скрин). Для выделенной ячейки это "2019-03-01 Fuji". Нужна функция, чтобы получить это значение:
Код
set xItem = Selection.PivotItem
strOrder = GetParentData( xItem, "Код заказа")

Public Function GetParentData( xItem as Excel.PivotItem, ByVal xFieldName as string) as Variant
   ????
Next

Кто подскажет, как это можно? Лопатить Range'ы влево и вверх как-то не хочется... Хотя, если это единственный путь - то пусть.

Может, можно через PivotCache залезть?

Показатели NPV, вычисленные по годовому и месячному дисконту, неравны
 
Добрый день, коллеги!

Возможно, вопрос скорее математический, чем по Excel, но все же. В многочисленных примерах в интернете (на planetaexcel в том числе) период для расчета NPV - год. Есть функция ЧПС, есть стандартная формула, все вроде просто.

Понадобилось тут рассчитать NPV с периодом месяц. В самом деле, какая разница - нужен только денежный поток по периодам и дисконт за этот период. Так как дисконт обычно указывается годовой, помесячный дисконт вычисляем по формуле:
=СТЕПЕНЬ((1+ДисконтГод);(1/12))-1
//(12, естественно = количество месяцев в году)
А дальше шок: если вычислить два NPV отдельно по месяцам и по годам, то они будут неравны! То есть, вот эти две функции...
=ЧПС(ДисконтМесяц; ДиапазонДДС_ПоМесяцам)
и
=ЧПС(ДисконтГод; ДиапазонДДС_ПоГодам)

...на одних и тех же цифрах дадут разные результаты (см. скрин). Причем не "в рамках погрешности", а солидно -  за год почти на 13% при дисконте 30%. Проверил не через ЧПС, а через стандартную формулу:
=СальдоНаКонецГода/СТЕПЕНЬ((1+ДисконтГод);КоличествоПериодов)
и просто посчитал сумму дисконтированных оборотов по месяцам (см.скрин, ячейка D24). Получил те же значения, что и через ЧПС.

Как так может быть? Что-то неправильно в формулах?

ПРИМЕЧАНИЕ: 1) Для упрощения картины - денежный поток в месяц одинаковый (100 рублей), всего 1 год, начальные инвестиции не учитываем.
2) Желтые ячейки - вычисляемые показатели, синие - вводимые вручную.
Изменено: skogkatt - 11.10.2017 22:37:07 (исправил грамматическую ошибку)
Поиск вхождений по списку искомых значений (не работает готовое решение)
 
Добрый день, коллеги.

Помогите разобраться, почему не работает найденное на форуме решение. Точнее, иногда работает, а иногда нет.
Задача: есть список паттернов (потенциальных вхождений), которые надо найти в строке.
Желаемый результат: ИСТИНА если хотя бы один паттерн найден, ЛОЖЬ, если не найден ни один.
(конечный результат - условное форматирование списка значений, найдены паттерны или нет)

Подходящее решение нашел вот тут http://www.planetaexcel.ru/forum/index.php?PAGE_NAME=message&FID=8&TID=6361
Полностью скопированная формула из файла решения работает, а если ее изменить под другие нужды - нет!

В прилагаемом файле формула в столбце 3 дает нужный результат (это копия формулы из найденного решения), а более простая в столбце 2 не работает (ищет только первый паттерн).

Если прогнать формулы через пошаговое вычисление, то видно, что для формулы из столбца 3 вычисляется массив констант, а для формулы из столбца 2 - только первое значение. Причем происходит это, видимо, потому, что ссылка на массив паттернов появляется в формуле 2 раза.

По какой причине такое происходит?
Изменено: skogkatt - 09.07.2017 21:09:45 (опечатка в слове "пошаговое", искажающая смысл)
Страницы: 1
Наверх