Выбираешь ячейку - появляется форма
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
If Range("e16").Value = Selection Then
UserForm4.Show
Else
End
End If
End Sub
Надо чтобы сабж, а в данном случае при выделении диапозона - ошибка. И надо чтобы не е16, а допустим е10-е20 по очереди.
Простой пример - но уже глючит. Помог бы кто.
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
If Range("e16").Value = Selection Then
UserForm4.Show
Else
End
End If
End Sub
Надо чтобы сабж, а в данном случае при выделении диапозона - ошибка. И надо чтобы не е16, а допустим е10-е20 по очереди.
Конечно, ошибка, "If Range("e16").Value = Selection" совсем неправильно.
Чтобы форма выскакивала в диапазоне е10-е20, можно сделать If, например, так:
If Target.Column = 5 And Target.Row>=10 And Target.Row<=20 Then
Все остальное - оставь как есть.
Конечно, ошибка, "If Range("e16").Value = Selection" совсем неправильно.
Чтобы форма выскакивала в диапазоне е10-е20, можно сделать If, например, так:
If Target.Column = 5 And Target.Row>=10 And Target.Row<=20 Then
Все остальное - оставь как есть.
А чтобы форма появлялась над выделенной ячейкой???
А чтобы форма появлялась над выделенной ячейкой???
К моему большому удивлению, вот такой код:
Load UserForm1
UserForm1.Top = 10
UserForm1.Left = 10
UserForm1.Show
End
отображает форму все равно по центру экрана (хотя соответствущие свойства меняет).
В тоже время разместив на форме кнопку с кодом
я получаю возможность двигать уже отображенную форму.
В общем, с налету не взялось, пока экспериментирую...
К моему большому удивлению, вот такой код:
Load UserForm1
UserForm1.Top = 10
UserForm1.Left = 10
UserForm1.Show
End
отображает форму все равно по центру экрана (хотя соответствущие свойства меняет).
В тоже время разместив на форме кнопку с кодом
я получаю возможность двигать уже отображенную форму.
В общем, с налету не взялось, пока экспериментирую...
Не понос, так золотуха :(
Как называется номер строки????
Тобишь форма.caption = другой столбец, таже строка
Что-то у меня с координацией никак. Здесь таргет строки, значит и ее номер он должен знать. Пробовал глепее через цикл
For i = 10 To 20
If Worksheets("Лист1").Cells(i, 5).Select = True Then
userform1.Caption = Worksheets("Лист1").Cells(i, 1).Value
End If
Next i
End Sub
Пишет ошибка отображения формы. Пробовал что-то еще все равно не работает (я уже и забыл что пробовал).
If Worksheets("Лист1").Cells(i, 5).Select = True Then
Что-то у тебя с синтаксисом ну совсем нелады. Я как человек понимаю, что ты хочешь сказать, а вот Эксель вряд ли поймет.
Как все в ВБА устроено?
Есть объекты. Куча объектов. Они бывают вложены друг в друга. Например, самый главный объект - Application (Приложение), в него вложены кроме прочих объекты WorkBook (Книга). В WorkBook, например, есть объекты WorkSheet (Лист) и т.д.
У каждого объекта могут быть свойства, методы и события.
Например, у листа есть свойство - Name - Имя ("Лист1"). Свойства можно менять (хотя и не все):
ActiveSheet.Name = "Temp",
сравнивать между собой:
If ActiveSheet.Name = "Temp" Then
и т.д.
Методы - это приказы.
Например, ActiveSheet.Delete - удалить. Приказы можно только отдавать. У них нет никаких значений.
Ну есть еще события, но сейчас неохотва про них писать. Так вот, Select - это метод. "Выделить!" - вот что такое Select. А Selection - это объект. А ты их оба раза запихиваешь в If. Так низя.
В общем, я тебе советую не пытаться сейчас написать супер-пупер-навороченную-программу, а реализовать свои алгоритмы максимально просто. Извини, но твой уровень еще не позволяет большего. Короче, руку набивай. :)
Совет отказаться от задуманого не ответ на вопрос. А последний вопрос сам победил :)
Наверно правда вопрос криво задал.
Просто надо
i = Target.Row
UserForm4.Caption = Worksheets("Лист1").Cells(i, 1).Value
вставить в самом верхнем вопросе. А номер строки мне нафиг не нужен. Но про место появления формы - вопрос остается открытым.
Совет отказаться от задуманого не ответ на вопрос. А последний вопрос сам победил :)
Наверно правда вопрос криво задал.
Просто надо
i = Target.Row
UserForm4.Caption = Worksheets("Лист1").Cells(i, 1).Value
вставить в самом верхнем вопросе. А номер строки мне нафиг не нужен. Но про место появления формы - вопрос остается открытым.
Про место появления формы - я пробую сейчас разные варианты. Если что получится приемлемое - то я сообщу.
Совет отказаться от задуманого не ответ на вопрос. А последний вопрос сам победил :)
Наверно правда вопрос криво задал.
Просто надо
i = Target.Row
UserForm4.Caption = Worksheets("Лист1").Cells(i, 1).Value
вставить в самом верхнем вопросе. А номер строки мне нафиг не нужен. Но про место появления формы - вопрос остается открытым.
Ответ на твое предыдущее высказывание:devil:
Private Sub UserForm_activate()
Вот это я забыл скопировать с последним вопросом. Но все равно не работает.А за критику спасибо (еще большее спасибо за помощь), у меня что методы, что еще что - я только учусь.
К моему большому удивлению, вот такой код:
Load UserForm1
UserForm1.Top = 10
UserForm1.Left = 10
UserForm1.Show
End
отображает форму все равно по центру экрана (хотя соответствущие свойства меняет).
В тоже время разместив на форме кнопку с кодом
я получаю возможность двигать уже отображенную форму.
В общем, с налету не взялось, пока экспериментирую...
Я тоже удивился, а потом обнаружил, что для формы
необходимо еще указать StartUpPosition (с нулем в нашем случае). Что-то MS перемудрил. Или недомудрил - могло бы выскакивать сообщение что .Top не работает без StartUpPosition .
UserForm1.StartUpPosition = 0
UserForm1.Top = 100
UserForm1.Left = 200
UserForm1.Show
А как определить позицию ячейки на экране?
А как определить позицию ячейки на экране?
Да, это хороший вопрос...
Если пользователь тыкает мышкой, то проблем нет, API нам в помощь, а вот если двигает выделение...
Я тоже удивился, а потом обнаружил, что для формы
необходимо еще указать StartUpPosition (с нулем в нашем случае). Что-то MS перемудрил. Или недомудрил - могло бы выскакивать сообщение что .Top не работает без StartUpPosition .
UserForm1.StartUpPosition = 0
UserForm1.Top = 100
UserForm1.Left = 200
UserForm1.Show
А как определить позицию ячейки на экране?
Ага! StartUpPosition - это клево. А вот с позицией ячейки теперь вторая закавыка.
Range("B10").Top и .Left возвращают позицию от левого угла листа (то есть для А1 они равны 0). А .Top и .Left у формы - от левого угла приложения. Сейчас пытаюсь найти координаты левого угла листа в окне приложения. ActiveWindow.Left - вроде как не помогает.
Да, это хороший вопрос...
Если пользователь тыкает мышкой, то проблем нет, API нам в помощь, а вот если двигает выделение...
Ну, через API - это неспортивно. :D
В принципе это реально.
Ща накодю, проверю и выложу...
Ну, через API - это неспортивно. :D
Поздравляю с юбелейным сообщением!:o
Поздравляю с юбелейным сообщением!:o
В смысле ЮБ-И-ЛЕЙНЫМ
В смысле ЮБ-И-ЛЕЙНЫМ
Да уж, и "Мега-Флудером" стал...
Кстати, админы форума всем с количеством сообщений больше 20, рекомендуют фотку свою зааватарить (80x80, <=8kb).
ща функцию допишу, протестите ее вместе, подкорректируем и можно раздавать :-)
Ладно, уговорил, тут в принципе все равно, можно и без API, тут сложность другая была и там API не могло никак помочь, просто некоторые начальные координаты легче через API было вытянуть, но это все ерунда ... и без него обойдемся
ща функцию допишу, протестите ее вместе, подкорректируем и можно раздавать :-)
С нетерпением жду. Интересно, как ты выкрутился... :)
Ход решение хорошо виден по комментариям, их я не жалел :-)
Нерешенные трудности: так до конца и не понял, почему CommandBar1.Top+CommandBar1.Height дает заниженные данные, которые зависят от общего кол-ва панели сверху (в данном случае сверху), если я выбираю самую нижнию из этих панелей.
Наверное там не учитываются бордюрчики между панельками, когда они друг по другом...это мое предположение,... вообщем добавил в конечный расчет соотв. вычисляемый коэффицент, который зависит от общего кол-ва панелек выше, небольшие ошибки при округлении, но вообщем попадает хорошо... +-2 пикселя :-)
x As Integer
y As Integer
End Type
Public Function KoordCell(Target As Range) As MyPoint
' возвращает координаты верхн. левого угла ячейки для активного окна.
Dim cb As CommandBar ' выдимые панели
Dim lhgtCommBar As Integer ' высота видимых панелей (которые сверху прикручены)
Dim lwdtCommBar As Integer ' ширина видимых панелей (которые сбоку прикручены)
Dim lhgtBarFormula As Integer ' высота "строка формулы"
Dim lhgtCapColumn As Integer ' высота заголовков столбцов
Dim lwdtCapRow As Integer ' ширина заголовков строк
Dim lhgtRange As Single ' сумм. высота ячеек
Dim lwdtRange As Single ' сумм. ширина ячеек
Dim rVis As Range ' видимый диапазон
Dim r As Range ' вспомогательная
Set rVis = ActiveWindow.VisibleRange
'проверка, входит ли Target в видим. ячейки
If Target.Row >= rVis.Row And Target.Row <= (rVis.Row + rVis.Rows.Count) And _
Target.Column >= rVis.Column And Target.Column <= (rVis.Column + rVis.Columns.Count) Then
' вычисляем высоту - Строка формул
If Application.DisplayFormulaBar Then
lhgtBarFormula = 15
End If
' вычисляем высоту/ширину - строка заголовки столбцов
If ActiveWindow.DisplayHeadings Then
lhgtCapColumn = 15
If rVis.Rows(rVis.Rows.Count).Row < 1000 Then
lwdtCapRow = 20
ElseIf rVis.Rows(rVis.Rows.Count).Row < 10000 Then
lwdtCapRow = 25
Else
lwdtCapRow = 30
End If
End If
' вычисляем высоту/ширину панелей (которые прикручены сверху/сбоку)
For Each cb In CommandBars
If cb.Visible = True Then
If cb.Position = msoBarTop Then ' ищем самую нижн. панель из верхних
If lhgtCommBar < cb.Top + cb.Height Then
lhgtCommBar = cb.Top + cb.Height
End If
End If
If cb.Position = msoBarLeft Then ' ищем самую правую панель из левых
If lwdtCommBar < cb.Left + cb.Width Then
lwdtCommBar = cb.Left + cb.Width
End If
End If
End If
Next cb
' не знаю почему, но cb.Top + cb.Height дает заниженные результаты
' пропорционально кол-ву панелей. Т.е. 2-точно, 3-(~-6), 4-(~-12), 5-(~-18) и т.д.
lhgtCommBar = lhgtCommBar - 6 * (lhgtCommBar \ 25 - 2)
' с cb.Left + cb.Width та же фигня, но коэфф. лучше брать =7
' lwdtCommBar = lwdtCommBar - 7 * (lwdtCommBar \ 27)
Debug.Print lhgtCommBar
' вычисляем сумм. высоту строк/столбцов
For Each r In rVis.Rows
If r.Row = Target.Row Then
Exit For
Else
If Not r.Hidden Then ' скрытые не учитываем
lhgtRange = lhgtRange + r.Height
End If
End If
Next
For Each r In rVis.Columns
If r.Column = Target.Column Then
Exit For
Else
If Not r.Hidden Then ' скрытые не учитываем
lwdtRange = lwdtRange + r.Width
End If
End If
Next
' вычисляем конечные итоги
KoordCell.x = Application.Left + ActiveWindow.Left + 3 + lwdtCommBar + lwdtCapRow + lwdtRange
KoordCell.y = Application.Top + ActiveWindow.Top + 17 + lhgtCommBar + lhgtBarFormula + lhgtCapColumn + lhgtRange
' ActiveWindow.Top + 17 - если окно maxim., то ActiveWindow.Top=-17,
' это потому что заголовок окна и бордюрчики, для этого я делаю +17
' ActiveWindow.Left + 2 - та же фигня, учитываем бордюрчик
Else
' указанный range не входит в видимый диапазон, возращаем нули
End If
End Function
Debug.Print lhgtCommBar
уберите ее там у себя в коде.
Dim mp As MyPoint
mp = KoordCell(Target)
UserForm1.StartUpPosition = 0
UserForm1.Top = mp.y
UserForm1.Left = mp.x
UserForm1.Show
End Sub
левый верхн. угол формы должен совпадать с левым верхним углом ячейки.... потыкайте и проверте :-)
P.S. Необходимо только добавить в Excel книжку какую-нибудь форму под названием - UserForm1
Да, вот еще, простой примерчик использования моей функции, если кого-нибудь возникнут проблемы:
Dim mp As MyPoint
mp = KoordCell(Target)
UserForm1.StartUpPosition = 0
UserForm1.Top = mp.y
UserForm1.Left = mp.x
UserForm1.Show
End Sub
левый верхн. угол формы должен совпадать с левым верхним углом ячейки.... потыкайте и проверте :-)
P.S. Необходимо только добавить в Excel книжку какую-нибудь форму под названием - UserForm1
Да-а-а...
Большой труд, Сереж! Это круто!!!
Удручает, что приходится так изворачиваться ради решения такой весьма естественной задачи. Мог бы дядя Билл и добавить пару логичных свойств для облегчения нашей программерской участи.
А что касается тестинга - то у меня для точного попадания нужно на 2 пикселя вправо сдвинуть (ксати, можно для эстетики и еще пикселей по 5 вправо-вниз - наподобие контекстного меню чтоб получалось).
Да, ну и конечно, все константы в программе должны зависеть от виндузовых установок типа "ширина границы окна" (это я чтоб поумничать ;) )
Думаю, ZABor должен быть доволен.
С пробовал добраться к нужному окну напрямую, через API, но у Excela все ячейки листа, скорилинги, статусбары и даже строка ввода формулы сидят в одном окне.
Т.е. для виндов все что внутри окна является просто набором красочных пикселей, а их прорисовка и реагирование на действия пользователей возложена на Excel. Так например и в Access сделано: там в открытой ленточной форме может быть ОЧЕНЬ много элементов-контролов и если их оформлять как окна и выдавать по хэндлу, то у win95-98 может теоретически закончится запас свободных хэндлов, поэтому прорисовку этих элементов Access берет на себя, а для виндов только форма является окном, а то что внутри не более чем рисунок..
Вообщем в Excel можно только к вышеуказанному окну подобраться и считать его координаты, тогда надо только будет учесть: строку формул, строку с заголовками ну и сами ячейки - по точнее немного будет, да и кода попроще, не нужно связываться с панелями, размещением окна книги внутри окна программы.... Но раз просили без API, то сделали без API (тем более, что все-таки Excel, Word не всегда безоблачно реагируют на вызовы функций API и если есть возможность, то лучше без них)
Да согласен, при таком "тупом" (нудным) подходе необходимо по хорошему учитывать все, и настройки виндов в том числе.
С пробовал добраться к нужному окну напрямую, через API, но у Excela все ячейки листа, скорилинги, статусбары и даже строка ввода формулы сидят в одном окне.
Т.е. для виндов все что внутри окна является просто набором красочных пикселей, а их прорисовка и реагирование на действия пользователей возложена на Excel. Так например и в Access сделано: там в открытой ленточной форме может быть ОЧЕНЬ много элементов-контролов и если их оформлять как окна и выдавать по хэндлу, то у win95-98 может теоретически закончится запас свободных хэндлов, поэтому прорисовку этих элементов Access берет на себя, а для виндов только форма является окном, а то что внутри не более чем рисунок..
Вообщем в Excel можно только к вышеуказанному окну подобраться и считать его координаты, тогда надо только будет учесть: строку формул, строку с заголовками ну и сами ячейки - по точнее немного будет, да и кода попроще, не нужно связываться с панелями, размещением окна книги внутри окна программы.... Но раз просили без API, то сделали без API (тем более, что все-таки Excel, Word не всегда безоблачно реагируют на вызовы функций API и если есть возможность, то лучше без них)
Дааааааааааааааааааааааааа!!!!!P(
Осталось только понять что там написано.
Да согласен, при таком "тупом" (нудным) подходе необходимо по хорошему учитывать все, и настройки виндов в том числе.
С пробовал добраться к нужному окну напрямую, через API, но у Excela все ячейки листа, скорилинги, статусбары и даже строка ввода формулы сидят в одном окне.
Т.е. для виндов все что внутри окна является просто набором красочных пикселей, а их прорисовка и реагирование на действия пользователей возложена на Excel. Так например и в Access сделано: там в открытой ленточной форме может быть ОЧЕНЬ много элементов-контролов и если их оформлять как окна и выдавать по хэндлу, то у win95-98 может теоретически закончится запас свободных хэндлов, поэтому прорисовку этих элементов Access берет на себя, а для виндов только форма является окном, а то что внутри не более чем рисунок..
Вообщем в Excel можно только к вышеуказанному окну подобраться и считать его координаты, тогда надо только будет учесть: строку формул, строку с заголовками ну и сами ячейки - по точнее немного будет, да и кода попроще, не нужно связываться с панелями, размещением окна книги внутри окна программы.... Но раз просили без API, то сделали без API (тем более, что все-таки Excel, Word не всегда безоблачно реагируют на вызовы функций API и если есть возможность, то лучше без них)
Пойду думать, что там выше написано!!!
Пойду думать, что там выше написано!!!
Ты про функцию или про рассуждения о месте окна в системе виндов?
Если про второе, то можешь поставить себе Spy++ или WinInspector и потыкать потом в разные окошки, много интересного увидишь, особенно мне нравиться Spy++ из VB.net, нахаляву и работает очень красочно и быстро 8)
Ну а про функцию, там вроде комментариев вроде все описал, но главное она работает универсально, так что можешь просто брать, использовать и ни очем не думать (и не куда не ходить... :) )