CALC Ответьте пожалуйста

Автор And589, 14 декабря 2011, 05:49

0 Пользователи и 1 гость просматривают эту тему.

And589

Скажите пожалуйста как примерно можно сделать
1) При нажатии мышкой на ячейку она закрашивается заливкой
2) При нажатии мышкой на ячейку появляется определенное число
3) При нажатии мышкой на другую ячейку, закрашенная ячейка уже без заливки, но в обрамлении вокруг
4) При нажатии мышкой на ячейку, в другой ячейке удаляются числа

Можно сделать только с помощью макросов, если да, то как примерно, имею в виду может быть есть определенные названия функций или действия для каждого пункта.

JohnSUN

#1
Посмотрел на время отправки сообщения и понял - наболело и нужно срочно ;D
В двух словах - да, это делается с помощью макросов.
Щелчок мышью вызывает событие. Это событие запускает макрос, которому сообщает, в каком месте произошло событие. Макрос проверяет, какая из ячеек получила курсором по башке, и выполняет одно из указанных действий - закрашивает, вписывает, обводит или чистит.

Для более подробного ответа потребуется время. И дополнительная информация: каким цветом закрашивать? Какое число писать? "Уже без заливки" - это значит заливку нужно стереть? Или вместо заливки рисовать рамку? "В другой"-"числа": это просто описка?

PS. Ну вот, прошло немного времени... Ответов на вопросы нет, значит, выкладываю так, как понял.
Старался в комментариях объяснить что к чему и откуда, но если не поймешь - лучше переспроси.

[вложение удалено Администратором]
Владислав Орлов aka JohnSUN
Благодарить-не зазорно.
Подарить благо создателям офиса, нашему ресурсу, мне

And589

Спасибо, если конкретней, чтобы можно было составить один макрос для примера.
Поле ячеек, например, квадрат 25 ячеек A1-E5 и ячейка F6, нажатие на ячейки левой кнопкой мыши.
1) При нажатии на любую ячейку в поле
a) выбранные ячейки получают заливку красного цвета
б) выбранные ячейки получает число 1

2) При нажатии на ячейку F6
а) удаляется обрамление со всех ячеек в поле
а) ячейки с красной заливкой в поле получают обрамление
б) заливка убирается со всех ячеек в поле
в) числа удаляются со всех ячеек в поле

Т.е. при выборе ячеек в поле они всегда получают заливку и число, а при нажатии на ячейку F6 вне поля, в ячейках удаляется заливка и число, но перед этим появление у ячеек с заливкой обрамления.

JohnSUN

#3
Ну, это не сильно отличается от того, что я уже написал. Сам переделаешь или вместе возьмемся?

Ну, не ответил... В общем, получится что-то вот такое:
REM Кнопка отпущена
Function MouseOnClick_mouseReleased(oEvt) As Boolean
Dim oCell As Object ' Ячейка, которая стала выделенной
Dim oSheet As Object ' Лист, на котором это произошло
Dim nColumn%, nRow% ' Номер колонки и строки, в которых находится текущая ячейка
Dim tmp ' Временная переменная на все случаи
REM В нашей задаче источник события мало чем может помочь - слишком много пересчетов
REM пришлось бы выполнить, чтобы вычислить текущую ячейку
REM Поэтому просто будем ориентироваться на ячейку, которая стала текущей (выделенной)
REM В результате щелчка
MouseOnClick_mouseReleased = False    ' Разрешить офису другие обработки этого события

oCell = ThisComponent.getCurrentSelection()
If oCell.getImplementationName() <> "ScCellObj" Then Exit Function ' Это не ячейка - диапазон или объект
oSheet = oCell.getSpreadsheet()
If oSheet.getName() <> "Лист2" Then Exit Function ' Это не второй лист - ничего не делаем

nColumn = oCell.getCellAddress().Column
nRow = oCell.getCellAddress().Row

If (nColumn < 5) AND (nRow < 5) Then ' Это область A1:E5
oCell.CellBackColor = RGB(255,0,0)
oCell.setValue(1)
ElseIf (nColumn = 5) AND (nRow = 5) Then ' Это ячейка F6
REM Копируем стуктуру, которая описывает рамку (левую границу)
tmp =  oCell.LeftBorder
REM Меняем в этой границе какие-то параметры (Color, InnerLineWidth, OuterLineWidth, LineDistance...)
tmp.Color = RGB(255,0,128)
tmp.LineWidth = 100
REM Очищаем все кроме числовых значений в области A1:E5
oSheet.getCellRangeByName("A1:E5").clearContents(1022) ' Чистим всё кроме 1(числа)
For nColumn = 0 To 4 ' Это очень плохой способ! Годится только для таких маленьких областей
For nRow = 0 To 4 ' Перебирать ячейки по одной в больших областях - очень тормознуто!
oCell = oSheet.getCellByPosition(nColumn, nRow)
If oCell.getValue() = 1 Then ' Наш клиент - вписана единичка
oCell.LeftBorder = tmp
oCell.BottomBorder = tmp
oCell.RightBorder = tmp
oCell.TopBorder = tmp
EndIf
Next nRow
Next nColumn
oSheet.getCellRangeByName("A1:E5").clearContents(1) ' А теперь чистим числа
EndIf
End Function


Будет непонятно - спрашивай!
Владислав Орлов aka JohnSUN
Благодарить-не зазорно.
Подарить благо создателям офиса, нашему ресурсу, мне

And589

Спасибо, немного получилось, но все равно не так, хотелось бы еще спросить. Я не изменял скрипт.
1) При нажатии на поле мышкой, клетки не закрашиваются, закрашиваются только если выбрана одна ячейка и в редактировании макроса нажать выполнить макрос (кнопку с зеленой стрелкой). Т.е. для закраски каждой ячейки необходимо переключение на окно макроса и нажатие запуска макроса.
2) При активации макроса быстрыми кнопками на листе Calc пишет "Ошибка сценария при выполнении сценария, Сообщение: wrong number of parameters!"
3) Где можно найти все функции для Basic calc? В справке, кажется нет описания.

neft

#5
В файле щелчок на С не работает в OpenOffice (ошибка в строке tmp.LineWidth=100).

Функция из второго кода не работает вообще.

JohnSUN

Извини, And589, я должен был сразу сообразить, что нужно рассказывать подробно.
Надеюсь, первый вариант решения (из Ответ #1) ты скачал?
Так вот, в этой книге полный набор макросов для решения задачи.
Главная процедура для всего это хозяйства - RegisterMouseClickHandler. Именно она запускает слушатель события "Чего-то_Нажали_На_Мышке". И именно она указана в качестве макроса на событие "Открытие файла". Это в Сервис - Настройка - События (см.картинку)
Эта процедура создает слушателя с помощью createUnoListener(). Параметры у этой createUnoListener - префикс и имя интерфейса.
И тут же натравливает этот listener на контроллер текущего документа. То есть теперь, если при активном текущем документе поклацать кнопками мыши, listener это услышит и будет выполнять макросы с указанным префиксом: нажимаем кнопку - запускается макрос  префикс_mousePressed, отпускаем её - запускается макрос  префикс_mouseReleased.
Ну и еще требуется обязательно для каждого слушателя создавать процедуру префикс_disposing(oEvt). Пусть даже она ничего и делать не будет, но написать нужно.
Все основные действия по щелчкам я вписал в процедуру MouseOnClick_mouseReleased.
Ну, там уже идет обычное программирование, без всех этих заумных слушателей и событий.
Смотрим, что осталось выделенным после отпускания кнопки. Ну, сам посуди - если на открытом листе Калковской книги мышью клацнуть, то ячейка по которой кликнул, станет выделенной. Так? Ну вот...
Проверяем, что выделилось. Вот тут ответ на твой первый вопрос. Если выделено больше одной ячейки - я ничего не делаю. Просто ты в описании задачи говорил всё время только про одну ячейку. Вот я именно так и написал.
У ячейки выдираем номер строки, в которой она находится, номер столбца и текущий лист (уже не номер, а объект - лист книги целиком, потом пригодится).
Ну, потом проверки на попадание ячейки в ту или другую область... И соответственно - реакции: закрашивать, обводить, вписывать или стирать.
Чтобы та функция, которую я привел в Ответ #3 работала нормально, ею нужно заменить точно такую же из файла. И вот тогда, в полном комплекте, всё заработает нормально. Ну, за исключением строчки с tmp.LineWidth. В LibreOffice эта строчка работает нормально, а вот в OpenOffice.org - не станет. Нет там такого свойства. Зато есть похожее - InnerLineWidth. То есть дописываем всего-то пять букв Inner и не кипишуем зазря
Надеюсь, с этим разобрались?

А вот по третьему вопросу... Тут, понимаешь ли, сложнее... Справочник такой есть, SDK называется. Можно скачать на официальном сайте. Или каждый раз лазить в его он-лайн версию... Вот, например, тот самый interface XMouseClickHandler
Но чтобы научится им пользоваться нужен определенный опыт программирования, понимание некоторых базовых понятий... Лично я все эти базовые понятия осваивал по книжкам Питоньяка - шикарная, должен тебе сказать, литература!
Ну, и в компанию к SDK, есть еще приятный инструмент, расширение MRI.

Всё понятно объяснил?

[вложение удалено Администратором]
Владислав Орлов aka JohnSUN
Благодарить-не зазорно.
Подарить благо создателям офиса, нашему ресурсу, мне

neft

Цитата: JohnSUN от 15 декабря 2011, 22:43
Чтобы та функция, которую я привел в Ответ #3 работала нормально, ею нужно заменить точно такую же из файла. И вот тогда, в полном комплекте, всё заработает нормально.

НЕ РАБОТАЕТ. (И именно после замены одной на другую)

JohnSUN

#8
Как говорила Масяна в одном из первых мультиков Куваева: "Покажь-ка, покажь-ка..."
Прицепи файл, который получился, к сообщению. Да! И версию своего офиса скажи!

PS. Знаешь, neft, я ведь не хотел отвечать. Ты попросил пару дней помолчать - мне не трудно... Для тебя и помолчать не жалко. Но, видимо, And589 очень хочет быстро разобраться. Помнишь время первого сообщения в топике?

[вложение удалено Администратором]
Владислав Орлов aka JohnSUN
Благодарить-не зазорно.
Подарить благо создателям офиса, нашему ресурсу, мне

neft

Вот
Ни в Libre, ни в Open

[вложение удалено Администратором]

JohnSUN

Ну? Нормально работает... То есть именно так, как в коде и написано... К предыдущему сообщению приложил файл - от твоего отличается только комментариями. А работает точно так же - верхний квадрат на Лист2 5х5 и ячейка F6 реагирует на мышь...
Владислав Орлов aka JohnSUN
Благодарить-не зазорно.
Подарить благо создателям офиса, нашему ресурсу, мне

neft

#11
ИЗВИНИ, просмотрел эту строчку (да я и не смотрел в код, думал, что или на Листе1, как в первом случае, либо на активном листе)
If oSheet.getName() <> "Лист2" Then Exit Function ' Это не второй лист - ничего не делаем

РАБОТАЕТ.

PS. Шабаш, пора спать.

And589

Спасибо за ответы. Да, я не заметил приложенный файл во втором посте. А можно еще спросить, относительно цвета.
1) Например, в этом поле первые выбранные любые пять ячеек были красного цвета, следующие пять ячеек синего цвета и т.д. Необходимо вводить определенные переменные или запоминать ячейки? Какой командой можно ввести очередь заливки разного цвета?
2) Можно ли в формулах ячеек с IF, чтобы ячейка изменялась, если определенная ячейка красного цвета? Т.е. например =IF(A1color = {(153,0,0)}; 1)

JohnSUN

#13
Цитата: And589 от 16 декабря 2011, 19:131) Например, в этом поле первые выбранные любые пять ячеек были красного цвета, следующие пять ячеек синего цвета и т.д. Необходимо вводить определенные переменные или запоминать ячейки?
Можно и так, и эдак. Для небольшого диапазона ячеек - ну, как у тебя, 5х5 или чуть больше - не трудно пробежаться по всем и пересчитать по головам. Обратил внимание на комментарий к циклам? Насчет плохого способа?
А можно хранить общее количество закрашенных ячеек.
И вычислять номер следующего цвета через, например, остаток от деления результата целочисленного деления. Звучит страшновато, а на самом деле это просто формула
<индекс очередного цвета> = Int((<счетчик закрашенных ячеек>)/<количество ячеек >) MOD <количество цветов>
То есть, подсчитывается количество уже закрашенных ячеек, делится нацело на количество ячеек одного цвета. Ты хотел по пять штук одного цвета? Значит на пять и делится. И берется остаток от деления на количество цветов.
Допустим, хотим красить по пять ячеек... Нет, для примера слишком много. Давай по три ячейки в шесть цветов. Тогда начинаем щелкать мышкой и считать:
№ щелчкаИндекс цвета
00Это у нас идет первый цвет
10
20
31Начался новый цвет
41
51
62Начался следующий цвет
72
82
93Опять перещелкнули раскраску
103
113
124И еще раз
134
144
155Это уже шестой раз
165
175
180И опять начинаем сначала
190
200
211
Вот этот индекс цвета и считается формулой Int((cntColor)/3) MOD 6 А по полученному индексу выдергиваешь из заранее подготовленного массива или рассчитываешь каким-то образом нужный цвет.
Беда в том, что сохранить значение счетчика щелчков между вызовами процедуры не очень простая задача - просто в переменной это значение не сохранишь, все равно обнулится.
Цитата: And589 от 16 декабря 2011, 19:13Какой командой можно ввести очередь заливки разного цвета?
"М? Пе-ре-ве-ди..." (с) "Москва слезам не верит"
Очередь? Заливки? Цвета?
А! Кажется, понял. Как заставить программу перебирать цвета последовательно? Ну, я бы сделал что-то вроде
Dim colors
colors = Array(RGB(255,0,0), RGB(255,255,0), RGB(255,0,255), RGB(0,255,0), RGB(0,255,255), RGB(0,0,255), RGB(128,128,128))
А потом для раскраски пользовался бы выражением типа colors(Int((indColor)/5) MOD 7)
Цитата: And589 от 16 декабря 2011, 19:132) Можно ли в формулах ячеек с IF, чтобы ячейка изменялась, если определенная ячейка красного цвета? Т.е. например =IF(A1color = {(153,0,0)}; 1)
Это можно. (Это ссылка на решение)
PS. Так лучше?
Владислав Орлов aka JohnSUN
Благодарить-не зазорно.
Подарить благо создателям офиса, нашему ресурсу, мне

And589

ЦитироватьPS. Так лучше?
Да, опять спасибо, просто сложно в том, что я только переменные изменяю и параметры добавляю, то, что ты написал понял, но честно сказать, не знаю как написать правильно эту функцию в макросе. Макросы никогда не писал, а тем более из словарного совета написать полностью скрипт, даже небольшой. Я вписал 3 строчки, выдал ошибку, но наверно и не могло заработать.
ЦитироватьОчередь? Заливки? Цвета?
Да, первые выбранные в поле 5 ячеек одного цвета, другие по 5 других цветов.
Цитировать(Это ссылка на решение)
Я пробовал, добавил новую фенкцию после первой функции в макросе, в ячейку B2 добавил =BACKCOLOR("A" & ROW()), написал ошибку переменная не определена в строке oSheet = ThisComponent.CurrentController.ActiveSheet.