Доброго дня, Планетяне! Прошу помочь с некоторыми проблемами нумерации: самая главная проблема - в диапазон нумерации "врезаются" объединённые ячейки (не протянуть стандартным способом функцию). Помогите с макросом, который бы обходил эту проблему (макрос стандарной нумерации прикрепляю. если вдруг понадобится). Вторая субпроблема (прошу модераторов не ругаться, т.к. строго по теме): сочинение макроса для порядковой нумерации одно- и многостраничных документов. Тут есть рабочая длинная полифункция (совокупность нескольких функций), которая отлично работает, но хотелось бы макрос для удобства и простоты использования. Суть макроса (работает с выделенным диапазоном): 1. ориентируется на диапазон слева от выделенного (количество листов) 2. для первой ячейки выделенного диапазона а = 1, (если n=1), в противном случае a = 1–1+n, (a = значение в заполняемой ячейке; n = количество листов в виде числа; numup = число/диапазон в ячейке над заполняемой; разделитель диапазонов "–" = "Alt+0150") 3. во второй и всех последующих ячейках нумерация производится по следующему правилам: а) в ячейке выше нет разделителя и в ячейке слева стоит 1: a = numup+1 б) в ячейке выше нет разделителя и в ячейке слева стоит число большее 1: a = numup+1–numup+n в) в ячейке выше есть разделитель и в ячейке слева стоит 1: a = delright+1,(delright - число справа от разделителя) г) в ячейке выше есть разделитель и в ячейке слева стоит число большее 1: a = delright+1–delright+n
Я всё это выполнял функциями ЕСЛИ, ЕЧИСЛО, ПОИСК, и UDF "Substring" от Николая Павлова. Простите, если выглядит как ТЗ - хотел быть полезен…
Так как это описание многим даже читать лень и написано оно коряво и непонятно, есть макрос в посте #23 (нерабочий, но я старался), в котором пошагово закомментированы выполняемые процедуры…
P.S.: знаю про то, что объединённые ячейки есть абсолютное зло в Excel, но такая форма реестра. Иногда выкручиваюсь через выравнивание по центру выделения (визуально одинаково). но подходит далеко не всегда
05-10-2016. Все задачи решены с помощью уважаемых Sanja и JayBhagavan (окончательные варианты в посте #44). Спасибо им огромное! Заинтересованный пользовательalex1210 развил мысль в своей теме. Если кому интересно - загляните
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
Для конкретного столбца будет проще. Например для A
Код
Sub AutoNum()
Dim iCell As Range
Dim I As Long
I = 1
For Each iCell In Range("A2:A" & Cells(Rows.Count, 1).End(xlUp)).Cells
If iCell.MergeCells = False Then
iCell.Value = I
I = I + 1
End If
Next
End Sub
Согласие есть продукт при полном непротивлении сторон
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
Sub AutoNum()
Dim iCell As Range
Dim I As Long
Dim lRow As Long
I = 1
lRow = Cells(Rows.Count, 2).End(xlUp).Row
For Each iCell In Range("A2:A" & lRow).Cells
If iCell.MergeCells = False Then
iCell.Value = I
I = I + 1
End If
Next
End Sub
Sanja, спасибо большое))) всё работает - первая проблема решена кстати, как "склеивать" условия, чтобы и объединённые пропускать и скрытые? Что то типа If iCell.Rows.EntireRow.Hidden = False And If iCell.MergeCells = False?
Код
'Нумерация по порядку необъединённых видимых ячеек первого столбца
'Автор: Sanja
'На основе макроса от: Tebenkov Igor
'Тема на форуме: http://www.planetaexcel.ru/forum/index.php?PAGE_NAME=message&FID=1&TID=82499&TITLE_SEO=82499-numeratsiya-s-diapazonami-i-bez-ignoriruya-obedinyennye-yacheyki&MID=689121&result=edit#message689121
'====================================================================================================================================================================================================================
Sub AutoNumAMerge()
Dim iCell As Range
Dim I As Long
Dim lRow As Long
Application.ScreenUpdating = False
lRow = Cells(Rows.Count, 2).End(xlUp).Row
For Each iCell In Range("A2:A" & lRow).Cells
With iCell
If Not .MergeCells And Not .Rows.EntireRow.Hidden Then
I = I + 1
iCell.Value = I
End If
End With
Next
Application.ScreenUpdating = True
End Sub
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
Sub AutoNum()
Dim iCell As Range
Dim I As Long
Dim lRow As Long
lRow = Cells(Rows.Count, 2).End(xlUp).Row
For Each iCell In Range("A2:A" & lRow).Cells
With iCell
If Not .MergeCells And Not .Rows.EntireRow.Hidden Then
I = I + 1
iCell.Value = I
End If
End With
Next
End Sub
Sanja, спасибо большое за разъяснение!)))) если есть желание - помогите, пожалуйста, с макросом для нумерации документов (вариант №2) - а то формулами долго каждый раз громоздить…
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
Jack Famous, неужели Вы и вправду думаете что кому-то интересно разбираться с задачей в ТАКОЙ ее постановке? Что такое n (тем более 1-1+n. Вы бы сами поняли?). У Вас за 700 сообщений и до сих пор не понятно, что самый лучший вариант вопроса это ФАЙЛ, в котором Как есть - Как надо?
Согласие есть продукт при полном непротивлении сторон
Sanja, так он же есть в шапке а текстовуха - это методика, по которой я функцию писал, только каждый раз так делать уж очень утомительно… Аргументы в ней также описаны. А "-" в формулах это не минус а длинное тире (символ набираемый через Alt+0150). Дело в том, что после вычислений я преобразовываю формулы в значения и, если использовать обычное тире, нужны дополнительные "костыли" от автоматического преобразовывания нумерации типа "1-6" (листы с первого по шестой) в дату 1 июня текущего года)))
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
Доброго утра, Планетяне! Ещё раз подниму тему и задам вопрос))) погуглил, посмотрел - есть вариант "решения в лоб", как то средствами VBA вписывать в активную ячейку формулу по образу и подобию ActiveCell.FormulaLocal = "=СУММ(A1;B1)" - и тут возникают вопросы… Во-первых в используемом для нумерации наборе формул присутствует UDF - можно ли ёё вписывать в VBA также, как стандартные? Если да, то нужно ли, чтобы эта UDF была в том же модуле, что и макрос на введение формулы или достаточно того, что она есть в PLEX? Ну и наконец: блин, это вообще не бред ли - вводить формулу через VBA в данном случае? Может запариться с самостоятельной UDF или макросом для автонумерации?…
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
alex1210, решил всё-таки написать макрос - ждите обновления
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
Прошу помощи у мастеров VBA. Первый раз ДЕЙСТВИТЕЛЬНО помощи, а не сделать вместо))))))) Попытался составить код по рабочей функции из примера - ошибки синтаксиса… Подскажите, пожалуйста, где косяк и как можно улучшить код… Привожу код здесь. Файл пример заменил в шапке и также дублирую здесь
Код
Sub AutoNumInReg()
Dim iCell As Variant
Dim leftcell As String
Dim upcell As String
Dim strDelim As String
strDelim = Application.InputBox("Введите символ-разделитель", "Определение разделителя")
If strDelim = "10" Then strDelim = Chr(10)
If strDelim = "" Then End
iCell = ActiveCell
leftcell = ActiveCell(, 0)
upcell = ActiveCell(0)
Selection.Cells(1).Value = 1
For Each iCell In Selection
If InStr(upcell, strDelim, 1) <> 0 And leftcell > 1 Then
iCell = Value.Split(upcell, strDelim)(1) + 1 & strDelim & Value.Split(upcell, strDelim)(1) + Value.leftcell
iCell = Value.iCell
ElseIf InStr(upcell, strDelim, 1) <> 0 And leftcell = 1 Then
iCell = Value.Split(upcell, strDelim)(1) + 1
iCell = Value.iCell
ElseIf InStr(upcell, strDelim, 1) = 0 And leftcell > 1 Then
iCell = Value.upcell + 1 & strDelim & Value.upcell + leftcell
iCell = Value.iCell
ElseIf InStr(upcell, strDelim, 1) = 0 And leftcell = 1 Then
iCell = Value.upcell + 1
iCell = Value.iCell
Else: End
Next
Next
Next
Next
End If
End If
End If
End If
End Sub
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
JayBhagavan, спасибо большое - ошибка синтаксиса пропала (не знал про "отбивку" пробелами). Однако, там, похоже совсем жесть - запутался в циклах For…Next и If…End If
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
JayBhagavan, большое спасибо за совет. Понял про постановку .Value - остальное (про циклы) никак не получается ((( Непонятно, когда "втыкать" End If, Else и Next и есть ли различие при использовании ElseIf (брал из примера отсюда и отсюда) Помогите пожалуйста - только начинаю самостоятельно писать
обавил примечания в код и существенно его перелопатил - ошибки, к сожалению, остались (хоть и изменились). Привожу код здесь. Файл-пример изменил в описании и дублирую тут.
Код
Sub AutoNumInRegister()
Dim cl As String
Dim leftcell As String
Dim upcell As String
Dim xRng As Range
Dim fromup As Integer
Dim finder As Byte
strDelim = "–" 'задаём разделитель между начальным и конечным номером (для мнгогострочных документов)
Set xRng = Selection
I = 1
cl = xRng.Cells(I) 'назначаем переменную для любой I ячейки выделенного диапазона
leftcell = xRng.Cells(I).Offset(0, -1) 'назначаем переменную для ячейки, слева от активной
upcell = xRng.Cells(I).Offset(-1, 0) 'назначаем переменную для ячейки, сверху от активной
fromup = Split(upcell, strDelim)(1).Value 'назначаем переменную для числа, взятого после разделителя из ячейки сверху от активной
finder = InStr(upcell, strDelim, 1) 'назначаем переменную для определения наличия разделителя в ячейке сверху от активной
If xRng.Cells(1, 0).Offset(0, -1) = 1 Then xRng.Cells(1, 0) = 1 'если число слева от первой ячейки = 1, то в первой ячейке 1
Else
xRng.Cells(1, 0) = 1 & strDelim & 1 + xRng.Cells(1, 0).Offset(0, -1).Value 'если нет, то "1разделитель1+число слева от первой ячейки (например, если в первом документе 5 страниц, то нумератор должен поставить "1-6", то есть с первой по шестую)
For I = 2 To xRng.Rows.Count 'цикл со второй ячейки и до конца выделенного диапазона
If finder <> 0 And leftcell > 1 Then 'если в ячейке выше активной присутствует разделитель и число слева больше 1, то…
cl = fromup + 1 & strDelim & fromup + leftcell 'значение в ячейке = число второе от разделителя в верхней ячейке + 1, разделитель, число второе от разделителя в верхней ячейке + число в левой ячейке
ElseIf finder <> 0 And leftcell = 1 Then 'если в ячейке выше активной присутствует разделитель и число слева = 1, то…
cl = fromup + 1 'значение в ячейке = число второе от разделителя в верхней ячейке + 1
ElseIf finder = 0 And leftcell > 1 Then 'если в ячейке выше активной нет разделителя и число слева больше 1, то…
cl = upcell + 1 & strDelim & upcell + leftcell 'значение в ячейке = число в верхней ячейке + 1, разделитель, число в верхней ячейке + число в левой ячейке
ElseIf finder = 0 And leftcell = 1 Then 'если в ячейке выше активной нет разделителя и число слева = 1, то…
cl = upcell + 1 'значение в ячейке = число в верхней ячейке + 1
Else: End 'если ни одно условие не выполняется, то выход
End If
Next I
End Sub
Изменено: Jack Famous - 05.10.2016 10:25:56(Чуть изменил код)
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
Jack Famous, сделайте файл с двумя листами: 1) что есть на входе (без каких либо изменений с Вашей стороны); 2) что должно быть на выходе (сделанное Вами вручную без макросов). Я пока не понимаю из выложенных файлов что из чего должно получиться.
Формула массива (ФМ) вводится Ctrl+Shift+Enter Memento mori
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
1) вместо объед. яч. исп. выравнивание по центру выделения; 2) для удобства завёл две именованные формулы (суммирование до текущей строки + 1 (если кол-во - число) и суммирование с кол-ом в текущ. строке); 3) получилась такая формула для D4: =ЕСЛИ(ЕЧИСЛО($C4);сум_до&ЕСЛИ(сум_до=сумм_с;"";"-"&сумм_с);"") Для удобства её ввода в соотв. ячейки отфильтруйте строки без пустого кол-ва листов.
JayBhagavan, у меня уже есть рабочая формула (в примере она также есть). Я хотел сделать макрос, делающий тоже самое в 1 щелчок (формула хоть и спасает, но довольно длинная и хотелось совсем уйти от этого). Кроме того, функцию после протягивания нужно преобразовать в значения и вручную (или через поиск по форматам) удалять значения в "визуально объединённых" ячейках - короче, тот ещё геморрой)) С объединёнными ячейками помог Sanja - можно в коде их просто пропускать. Про выравнивание по центру знаю, но выгрузка из сводной именно так происходит (с объединёнными) и на огромных реестрах преобразовать объединённые в такие вручную долго, а макросами - отдельная тема Всё равно спасибо, за то, что не прошли мимо…
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
JayBhagavan, спасибо за альтернативную функцию без использования UDF , но так как я храню все макросы и UDF в личной надстройке - они доступны в любой книге Excel, так что лично для меня - это не проблема, но, думаю, кому-то будет намного удобнее))
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
Option Explicit
Sub jjj_numerator()
Dim rngTarget As Range, arr(), c&, r&, c_n&, r_n&, sum1, sum2
Const lN_DOC& = 1
Const lQ_PAGES& = 3
Const lN_PAGES& = 4
Set rngTarget = UsedRange
arr = rngTarget.Value
r_n = UBound(arr, 1)
c_n = UBound(arr, 2)
sum1 = 0
sum2 = 0
For r = 1 To r_n
If IsNumeric(arr(r, lN_DOC)) Then
If IsNumeric(arr(r, lQ_PAGES)) Then
If r > 1 Then sum1 = jjj_arr_sum_by_col(arr, lQ_PAGES, 1, r - 1) + 1
sum2 = arr(r, lQ_PAGES) + sum1 - 1
If sum1 > 1 And sum2 > sum1 Then
arr(r, lN_PAGES) = sum1 & "-" & sum2
Else
arr(r, lN_PAGES) = sum2
End If
End If
End If
Next r
rngTarget.Value = arr
End Sub
Function jjj_arr_sum_by_col(ByRef arrIn, ByVal lTrgtCol&, ByVal lRowStart&, ByVal lRowEnd&)
Dim i&
jjj_arr_sum_by_col = 0
For i = lRowStart To lRowEnd
If IsNumeric(arrIn(i, lTrgtCol)) Then jjj_arr_sum_by_col = jjj_arr_sum_by_col + arrIn(i, lTrgtCol)
Next i
End Function
вариант 2 (попроще)
Код
Option Explicit
Sub jjj_numerator()
Dim rngTarget As Range, arr(), c&, r&, c_n&, r_n&, sum1, sum2
Const lN_DOC& = 1
Const lQ_PAGES& = 3
Const lN_PAGES& = 4
Set rngTarget = UsedRange
arr = rngTarget.Value
r_n = UBound(arr, 1)
c_n = UBound(arr, 2)
sum1 = 0
sum2 = 0
For r = 1 To r_n
If IsNumeric(arr(r, lN_DOC)) Then
If IsNumeric(arr(r, lQ_PAGES)) Then
sum1 = sum2 + 1
sum2 = arr(r, lQ_PAGES) + sum2
If sum2 > sum1 Then
arr(r, lN_PAGES) = sum1 & "-" & sum2
Else
arr(r, lN_PAGES) = sum2
End If
End If
End If
Next r
rngTarget.Value = arr
End Sub
Изменено: JayBhagavan - 05.10.2016 11:46:28(добавил вариант 2)
Формула массива (ФМ) вводится Ctrl+Shift+Enter Memento mori