[Решено] Объединение ячеек

Автор Massaraksh7, 9 мая 2024, 20:33

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

Massaraksh7

Разве это правильно, что getIsMerged сообщает об участии в объединении только одной ячейки из объединения?

mikekaganski

С уважением,
Михаил Каганский

Massaraksh7

#2
Цитата: mikekaganski от  9 мая 2024, 20:43Да.
Могу согласиться с тем, что такой факт имеет место, но, вот, что это правильно - не могу  :)
Но, за информацию, в любом случае, спасибо.

Massaraksh7

На скорую руку как-то так получилось, но подозреваю, что при увеличении числа данных и объединённых регионов, скорость обработки будет резко падать.

sokol92

Насколько я понимаю, при вызове метода getIsMerged анализируется первая (левая верхняя) ячейка диапазона ячеек.
Если эта ячейка является левой верхней ячейкой диапазона объединенных ячеек, то возвращается True.

Для справки. Аналогичное свойство Excel Range.MergeCells возвращает:
  • True   все ячейки диапазона входят в диапазон объединенных ячеек
  • False  ни одна ячейка диапазона не входит в диапазон объединенных ячеек
  • Empty  в иных случаях

Цитата: Massaraksh7 от  9 мая 2024, 23:39На скорую руку как-то так получилось
@Massaraksh7, коллега, вряд ли стоит тексты макросов показывать в виде картинок. При желании участника форума проанализировать тексты макросов ему придется выполнять работу по распознаванию графических образов, что вряд ли эффективно. Проще прикреплять файлы или оформлять макросы как текст.
Владимир.

Massaraksh7

Цитата: sokol92 от 10 мая 2024, 18:11вряд ли стоит тексты макросов показывать в виде картинок.
Хорошо.
dim mrng(),sheet
dim nRange as integer

Sub MergeCells
sheet = ThisComponent.Sheets.getByIndex(0)
nRange = 0
fillMergedAreas
for i=0 to 4
  for j=0 to 4
    if CheckMerge(i,j) then sheet.getCellByPosition(j,i+10).setString("Yes")
    if not CheckMerge(i,j) then sheet.getCellByPosition(j,i+10).setString("No")
  next j
next i 
end sub

function CheckMerge(row,col)
CheckMerge = False
for i=0 to nRange-1
  if row>=mrng(i).StartRow and row<=mrng(i).EndRow and col>=mrng(i).StartColumn and col<=mrng(i).EndColumn then
    CheckMerge = True
    exit function
  end if
next i   
end function

Sub fillMergedAreas
    ucf = sheet.getUniqueCellFormatRanges()
    for each ranges in ucf
        rgtest = ranges.getByIndex(0)
        if rgtest.getIsMerged() then
            for each rg in ranges
                rgm = getMergedRegion(rg)
                redim preserve mrng(0 to nRange)
                mrng(nRange) = rgm.getRangeAddress()
                nRange = nRange + 1
            next
        endif
    next
End Sub

Function getMergedRegion(oRange):
Dim oCursor
    oCursor = oRange.getSpreadsheet().createCursorByRange(oRange)
    oCursor.collapseToMergedArea()
    getMergedRegion = oCursor
End Function
Цитата: sokol92 от 10 мая 2024, 18:11Аналогичное свойство Excel Range.MergeCells возвращает:
Тут дело немного в другом. В VBA Excel я сразу получал адрес диапазона, в который ячейка попадает, неважно, левая верхняя она, или нет (код на Lazarus, но это неважно):
function IsMerged(row,col:integer):string;
begin
Result:=ICells.Item[row,col].MergeArea.Address;
end;
А здесь я такого не нашёл, и для этого нужны дополнительные телодвижения.

sokol92

А разве функция getMergedRegion из Вашего макроса не делает это же самое?
result=getMergedRegion(oRange).rangeAddress
Владимир.

Massaraksh7

Цитата: sokol92 от 10 мая 2024, 18:50А разве функция getMergedRegion из Вашего макроса не делает это же самое?
Ну да. Перемудрил. Тогда ещё проще:
Sub MergeCells
sheet = ThisComponent.Sheets.getByIndex(0)
for i=0 to 4
  for j=0 to 4
    aRange=sheet.getCellByPosition(j,i)
    rng=getMergedRegion(aRange)
    sheet.getCellByPosition(j,i+10).setString(rng.absoluteName)
  next j
next i 
end sub

Function getMergedRegion(oRange):
Dim oCursor
    oCursor = oRange.Spreadsheet().createCursorByRange(oRange)
    oCursor.collapseToMergedArea()
    getMergedRegion = oCursor
End Function

Massaraksh7

Вот так наглядней.

sokol92

#9
В этом сообщении коллега @Villeroy демонстрирует высокоэффективный метод для определения всех диапазонов объединенных ячеек.

Кстати в Excel VBA подобная задача решается через применение метода Range.Find (с заданием параметра SearchFormat) и многократное применение метода Range.FindNext. На примере файла Villeroy'я Calc работает намного быстрее, чем Excel (в "родных" форматах). 

Владимир.

Massaraksh7

Это я видел. И даже использовал в своём коде в сообщении #5. Но у меня сейчас стоит именно задача группировки ячеек по попаданию в один диапазон.

sokol92

Эту тему (как и другие) будут изучать будущие читатели, поэтому мое предыдущее сообщение может быть полезным для них.  :)
Владимир.

Massaraksh7

Цитата: sokol92 от 10 мая 2024, 20:08демонстрирует высокоэффективный метод для определения всех диапазонов объединенных ячеек.
Сам метод, без сомнения, эффективный. Проблемы с эффективностью могут начаться при последующей попытке сопоставления ячеек с попаданием в диапазоны при большом количестве ячеек и диапазонов.