Страницы: 1 2 След.
RSS
Поправка макроса с выпадающим календерем
 
Добрый день, имеется макрос с выпадающим календарем, как-то можно его исправить чтобы при повторном нажатии на ячейку где уже выставлена дата, дата не сбивалась пока не выберешь другую дату. Функция нужна т.к не работает отмена изменений с максросами.
 
Kraimon, закомментируйте или уберите
Код
Target = slancalendar.Value
 
Спасибо, то что нужно
 
вот пытаюсь сделать красиво (удобно)  :oops: - но что-то не получается... может, есть идеи у кого-нибудь? чтобы он выпадал рядом с ячейкой? пытаюсь, например, так (хотя как только не пыталась)
Код
Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean)
If Not Intersect(Target, Range("a:a,c1:c2")) Is Nothing Then
'slancalendar.Show

With Application
slancalendar.Top = .Top + Target.Height * Target.Row + slancalendar.Height / 2 'Target.Top
slancalendar.Left = Target.Left + Target.Width
slancalendar.Show
End With

'Target = slancalendar.Value
Cancel = True
End If
End Sub
сначала листа работает... когда прокручиваю лист вниз и по Double-Click пытаюсь вызвать календарь в столбце A:A - он как-то в самом низу или ещё дальше вне поля зрения появляется... в чём я неправа в вставленной конструкции With... End with?
P.S. в свойствах юзер-формы выставила .StartUpPosition= Manual
Изменено: JeyCi - 09.08.2016 21:04:40
чтобы не гадать на кофейной гуще, кто вам отвечает и после этого не совершать кучу ошибок - обратитесь к собеседнику на ВЫ - ответ на ваш вопрос получите - а остальное вас не касается (п.п.п. на форумах)
 
честно говоря, если выставить так (сама не поняла, что сказала в коде)
Код
With Application
slancalendar.Top = (Target.Top Mod Target.Row) + slancalendar.Height / 2 'Target.Top
slancalendar.Left = Target.Left + Target.Width
slancalendar.Show
End With
то хотя бы из поля зрения не пропадает (до 400-й яч)... но всё-таки ещё не совсем рядом с ячейкой..
Изменено: JeyCi - 10.08.2016 11:36:11
чтобы не гадать на кофейной гуще, кто вам отвечает и после этого не совершать кучу ошибок - обратитесь к собеседнику на ВЫ - ответ на ваш вопрос получите - а остальное вас не касается (п.п.п. на форумах)
 
JeyCi, воспользуйтесь наработками Nerv'a и не нервничайте. Это достаточно сложная тема.  :(
 
JeyCi, попробуйте поковыряться с этим кодом в модуле(код был взять из этой темы от nerv'a)
Думаю, неплохо бы запустить проверку положения обрабатываемой ячейки: если таргет находится в самом низу видимой области экрана, то скроллим лист вниз на высоту формы и вызываем саму форму(или вызываем форму в верхнем положении от ячейки). Как-то так  :)  
 
Цитата
Jungl написал:
или вызываем форму в верхнем положении от ячейки
Сам написал, сам решил:
Код
    With Form
        .Left = FullRange.Width * Zoom + PixelsToPoints(XOffset)
        vCells = Application.RoundUp(ActiveWindow.VisibleRange.Height / ActiveCell.Height - .Height / ActiveCell.Height, 0)
        aCell = ActiveCell.Row - Replace(Split(ActiveWindow.VisibleRange.Address, "$")(2), ":", "") - 1
        If vCells >= aCell Then
            .Top = FullRange.Height * Zoom + PixelsToPoints(YOffset)
        Else
            .Top = FullRange.Height * Zoom + PixelsToPoints(YOffset) - .Height
        End If
    End With
Насколько это точно срабатывает - решать вам.

p.s.
Код
Replace(Split(ActiveWindow.VisibleRange.Address, "$")(2), ":", "") - 1 
мне кажется бредом, но я никак не могу понять, как получить номер первой строки из диапазона ActiveWindow.VisibleRange  :sceptic:
 
Цитата
Skif-F написал: и не нервничайте
Skif-F, это вы о себе написали? так себе и пишите  ;)
Цитата
Jungl написал: Насколько это точно срабатывает - решать вам.
Jungl спасибо, работает #7... думала есть вариант проще... если докопаюсь до истины - тоже опубликую  :)
Изменено: JeyCi - 10.08.2016 06:23:05
чтобы не гадать на кофейной гуще, кто вам отвечает и после этого не совершать кучу ошибок - обратитесь к собеседнику на ВЫ - ответ на ваш вопрос получите - а остальное вас не касается (п.п.п. на форумах)
 
оставлю ещё один линк по вопросу выравнивания по ячейке появляющейся UF
Выбираешь ячейку - появляется форма
P.S. там в принципе веское замечание о том, что, работая с пикселями экрана - надо, вероятно, учитывать весь Window со всеми панелями - т.к. они все вносят свой вклад в местоположение на экране в пикселях... а т.к. (само собой разумеющееся) экран и настройка этих панелей не может быть одинакова у всех юзеров - поэтому с выравниванием по пикселям такие неоднозначные трюки приходится вытворять... думала, как-то кратко можно сделать в #5 - (когда нет желания нагромождать книгу кодом, если его и так много по др. вопросам) - но #5 в зоне видимости только до 400-й яч
p.p.s мой вывод: быстро, кратко и приемлемо остаётся только выставлять свойство юзерформы .StartUpPosition= CenterScreen или 2 (чтобы глазами и руками не лазить в края монитора)  8)
чтобы не гадать на кофейной гуще, кто вам отвечает и после этого не совершать кучу ошибок - обратитесь к собеседнику на ВЫ - ответ на ваш вопрос получите - а остальное вас не касается (п.п.п. на форумах)
 
JeyCi, это к выпадающему календарю имеет какое-то отношение? Создайте отдельную тему и там обсуждайте вопрос о пикселях
 
Цитата
vikttur написал: это к выпадающему календарю имеет какое-то отношение
да - речь была о выпадении его около ячейки (т.к. макрос на DoubleClick предложен ТСом) - правка для удобства пользования предложенной формой... имхо
Изменено: JeyCi - 10.08.2016 12:15:55
чтобы не гадать на кофейной гуще, кто вам отвечает и после этого не совершать кучу ошибок - обратитесь к собеседнику на ВЫ - ответ на ваш вопрос получите - а остальное вас не касается (п.п.п. на форумах)
 
Цитата
Kraimon написал: как-то можно его исправить чтобы при повторном нажатии на ячейку где уже выставлена дата, дата не сбивалась пока не выберешь другую дату
 
Добрый день. Хотел внедрить всплывающий календарь в свой проект. Нашел нужный вариант, но мне кажется, с таким кодом он у меня работать не будет. Не подскажете, как выйти из ситуации?

Option Explicit

Sub showcalendar()
slancalendar.Show
ActiveCell = slancalendar.Value
End Sub
Изменено: art_TD - 02.12.2024 15:08:10
 
Выйти с ситуации можно-приложив файл пример
 
Прикладывал, но что-то не дошло, видимо. Значит, попытка № 2.
 
Все работает. Нужно кликнуть на файл и правой клавишей выбрать Свойства и в открывшемся окне поставить галочку Разблокировать и нажать кнопку Ок.
 
У меня не было ни слова про то, что он не работает. Цитирую еще раз: "Хотел внедрить всплывающий календарь в свой проект", в свой проект - это значит, что я хотел бы добавить код в ДРУГОЙ файл Excel.
 
Слева вверху в редакторе кода в раскрывающемся списке Forms найдите модуль slancalendar. Мышкой перетащите в свой проект.
Либо индуский вариант: перенесите свой файл в файл с календарём Слэна, потом Лист1 удалите.
 
Зайдите в редактор  vba и экспортирует форму например на раб. Стол.
затем откройте свой файл и редакторе vba выберите import и форма попадёт в ваш проект.
 
МатросНаЗебре, спасибо большое за рекомендацию! Перенес модуль.  
 
Parovoznik, спасибо большое за вариант! Буду иметь в виду.
 
А не подскажете, может есть решение, как закрывать всплывающий календарь не выбором даты в нем, а нажатием на любую ячейку вне формы календаря?  
 
В свойствах формы поменяйте ShowModal на False.
Код примет вид.
Код
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
    If Target.Cells.Count > 1 Then Exit Sub
    If Intersect(Target, Range("B2")) Is Nothing Then
        slancalendar.Hide
    Else
        slancalendar.Show
        Target = slancalendar.Value
    End If
End Sub
 
МатросНаЗебре, спасибо! Поменял в свойствах формы, но код сам не изменился, скопировал Ваш код.

У меня закомментирована строка "Target = slancalendar.Value", как указано выше, чтобы выбранная ранее дата не исчезала, если просто закрываешь календарь. Но с таким кодом дата перестала выбираться. Нажимаю на дату, она не подставляется.

Private Sub Worksheet_SelectionChange(ByVal Target As Range)
   If Target.Cells.Count > 1 Then Exit Sub
   If Intersect(Target, Range("B20")) Is Nothing Then
       slancalendar.Hide
   Else
       slancalendar.Show
       'Target = slancalendar.Value
   End If
End Sub
 
Бррр, там какая-то чехарда с инициированием и обновлением даты. Мой совет был относительно
Цитата
написал:
как закрывать всплывающий календарь ... нажатием на любую ячейку
 
Да, я понял, форма с таким кодом закрывается при нажатии на любую ячейку. Но дата теперь не ставится.  
 
Как вариант, добавьте перед каждым скрытием формы изменение значения активной ячейки.
Код
    ActiveCell.Value = dt
    Me.Hide
 
В этом варианте проще вносить правки в одинаковые процедуры Label*_Click
Код
Option Explicit
Dim dt As Date, changing As Boolean
Dim d As Date, w&, mon&, cd As Date, dd As Date
Const ylen = 99 ' период дат, отображаемых в комбо годов - т.е. от 48 лет до указ даты и длиной в 99 лет
Dim dic As Object

Property Get Value() As Date
    Value = dt ' обеспечение обращения slancalendar.value
End Property

Private Sub combomon_Change()
    If changing Then Exit Sub ' отсекание циклических вызовов
    If combomon.ListIndex = -1 Then Exit Sub 'запрет произвольного ввода
    Call setcal(DateSerial(Val(comboyear.Text), combomon.ListIndex + 1, 1)) 'инициализация новой датой
    Application.SendKeys "{end}" 'чтобы без выделения
End Sub

Private Sub comboyear_Change()
    If changing Then Exit Sub ' отсекание циклических вызовов
    If comboyear.ListIndex = -1 Then ' при ручном вводе запрет инициализации до окончания ввода(enter)
        changing = True
        Exit Sub
    End If
    Call setcal(DateSerial(Val(comboyear.Text), combomon.ListIndex + 1, 1)) 'инициализация новой датой
    Application.SendKeys "{end}" 'чтобы без выделения
End Sub

Private Sub comboyear_KeyDown(ByVal KeyCode As MSForms.ReturnInteger, ByVal Shift As Integer)
If KeyCode = 13 Then ' реакция на нажатие интера
    changing = False ' разрешение последующей инициализации
    Call setcal(DateSerial(Val(comboyear.Text), combomon.ListIndex + 1, 1)) 'инициализация новой датой
End If
End Sub

Private Sub CommandButton1_Click()
    MsgBox "записано со слов вдохновения Новиковым А.Н.(aka slan)"
End Sub

Private Sub UserForm_Activate()
'Call setcal(Date) 'инициализация текущей датой
End Sub
Sub setcal(cd) ' cd - заданная дата
    ReDim y&(1 To ylen) ' выделение памяти по массив лет
    Dim cdt As Date, i&
    changing = True ' запрет циклических вызовов
    cdt = Date ' текущая дата - для выделения ее в календаре, если присутствует
    mon = Month(cd) ' месяц заданной даты
    combomon.ListIndex = mon - 1 ' отображение нужного месяца в списке
    y(ylen) = Year(cd) - Int(ylen / 2) ' начало перода дат в списке
    For i = 1 To ylen ' заполнение массива лет
        y(i) = y(ylen) + i
    Next
    comboyear.List = y ' заполнение списка лет
    comboyear.ListIndex = Int(ylen / 2) - 1 ' выделение нужного года
    d = cd - Day(cd) + 1 ' определение начала месяца
    w = Weekday(d, vbMonday) ' день недели начала месяца
    d = d - w ' дата начала заполнения календаря(понедельник недели начала месяца)
    For i = 1 To 42 ' заполнение чисел календаря
        dd = d + i
        With Me.Controls("label" & i) ' labelы заранее расположены в соответствующем порядке
            .Caption = Day(dd) ' число
            .Tag = CStr(dd) ' дата присваивается тэгу лэйбла, чтобы потом не искать
            If Month(dd) = mon Then .BackColor = &HC0E0FF Else .BackColor = &H80000004 ' закрашивание лэйблов месяца, соответствующего cd одним цветом, а остальных другим
            If dd = cdt Then .BackColor = &HFF8080 ' закрашивание текущей даты
        End With
    Next
    changing = False ' окончание инициализации

End Sub

Private Sub UserForm_Initialize()
    Set dic = CreateObject("Scripting.Dictionary")
    Dim cn As Control
    For Each cn In Me.Controls
        If TypeName(cn) = "Label" Then
            Set dic(cn.Name) = cn
        End If
    Next
    
    combomon.List = Array("январь", "февраль", "март", "апрель", "май", "июнь", "июль", "август", "сентябрь", "октябрь", "ноябрь", "декабрь")
Call setcal(Date) 'инициализация текущей датой
End Sub

Private Sub Label1_Click(): Labels_Click dic("Label1"): End Sub
Private Sub Label2_Click(): Labels_Click dic("Label2"): End Sub
Private Sub Label3_Click(): Labels_Click dic("Label3"): End Sub
Private Sub Label4_Click(): Labels_Click dic("Label4"): End Sub
Private Sub Label5_Click(): Labels_Click dic("Label5"): End Sub
Private Sub Label6_Click(): Labels_Click dic("Label6"): End Sub
Private Sub Label7_Click(): Labels_Click dic("Label7"): End Sub
Private Sub Label8_Click(): Labels_Click dic("Label8"): End Sub
Private Sub Label9_Click(): Labels_Click dic("Label9"): End Sub
Private Sub Label10_Click(): Labels_Click dic("Label10"): End Sub
Private Sub Label11_Click(): Labels_Click dic("Label11"): End Sub
Private Sub Label12_Click(): Labels_Click dic("Label12"): End Sub
Private Sub Label13_Click(): Labels_Click dic("Label13"): End Sub
Private Sub Label14_Click(): Labels_Click dic("Label14"): End Sub
Private Sub Label15_Click(): Labels_Click dic("Label15"): End Sub
Private Sub Label16_Click(): Labels_Click dic("Label16"): End Sub
Private Sub Label17_Click(): Labels_Click dic("Label17"): End Sub
Private Sub Label18_Click(): Labels_Click dic("Label18"): End Sub
Private Sub Label19_Click(): Labels_Click dic("Label19"): End Sub
Private Sub Label20_Click(): Labels_Click dic("Label20"): End Sub
Private Sub Label21_Click(): Labels_Click dic("Label21"): End Sub
Private Sub Label22_Click(): Labels_Click dic("Label22"): End Sub
Private Sub Label23_Click(): Labels_Click dic("Label23"): End Sub
Private Sub Label24_Click(): Labels_Click dic("Label24"): End Sub
Private Sub Label25_Click(): Labels_Click dic("Label25"): End Sub
Private Sub Label26_Click(): Labels_Click dic("Label26"): End Sub
Private Sub Label27_Click(): Labels_Click dic("Label27"): End Sub
Private Sub Label28_Click(): Labels_Click dic("Label28"): End Sub
Private Sub Label29_Click(): Labels_Click dic("Label29"): End Sub
Private Sub Label30_Click(): Labels_Click dic("Label30"): End Sub
Private Sub Label31_Click(): Labels_Click dic("Label31"): End Sub
Private Sub Label32_Click(): Labels_Click dic("Label32"): End Sub
Private Sub Label33_Click(): Labels_Click dic("Label33"): End Sub
Private Sub Label34_Click(): Labels_Click dic("Label34"): End Sub
Private Sub Label35_Click(): Labels_Click dic("Label35"): End Sub
Private Sub Label36_Click(): Labels_Click dic("Label36"): End Sub
Private Sub Label37_Click(): Labels_Click dic("Label37"): End Sub
Private Sub Label38_Click(): Labels_Click dic("Label38"): End Sub
Private Sub Label39_Click(): Labels_Click dic("Label39"): End Sub
Private Sub Label40_Click(): Labels_Click dic("Label40"): End Sub
Private Sub Label41_Click(): Labels_Click dic("Label41"): End Sub
Private Sub Label42_Click(): Labels_Click dic("Label42"): End Sub

Private Sub Labels_Click(oLabel As Object)
    dt = CDate(oLabel.Tag)
    ActiveCell.Value = dt
    Me.Hide
End Sub
 
В идеале бы такой календарь внедрить, как в ЕРП-системах. Можно мышью пролистывать месяцы, очень удобный функционал.  
Страницы: 1 2 След.
Наверх