Уважаемые форумчане, подскажите пожалуйста как сохранить нумерацию строк в таблице после сортировки. Нумерация идет не по порядку. Нужно чтобы при удалении какой либо строки она сохранялась и не пропадал удаленный номер. Файл прилагаю. СПАСИБО.
Уважаемые форумчане, подскажите пожалуйста как сохранить нумерацию строк в таблице после сортировки. Нумерация идет не по порядку. Нужно чтобы при удалении какой либо строки она сохранялась и не пропадал удаленный номер. Файл прилагаю. СПАСИБО.Egider
Sub ОбновитьНумерациюПослеУдаления() Dim i As Long On Error GoTo ErrorHandler
With Application .ScreenUpdating = False .DisplayAlerts = False .EnableEvents = False .Calculation = xlCalculationManual End With
With ThisWorkbook.Worksheets("Лист1")
Dim lastRow As Long lastRow = .Cells(.Rows.Count, "C").End(xlUp).Row
If ActiveCell.Row < 2 Or ActiveCell.Row > lastRow Then MsgBox "Выберите строку в диапазоне данных!", vbExclamation GoTo CleanExit End If
Dim arr As Variant arr = .Range("C2:D" & lastRow).Value
Dim восстановить As Boolean восстановить = True
Dim удаляемаяСтрока As Long удаляемаяСтрока = ActiveCell.Row - 1
Dim удалённоеЧисло As Long удалённоеЧисло = arr(удаляемаяСтрока, 2)
Dim newArr() As Variant ReDim newArr(1 To UBound(arr, 1) - 1, 1 To 2)
Dim outIndex As Long outIndex = 1
For i = 1 To UBound(arr, 1)
If i <> удаляемаяСтрока Then newArr(outIndex, 1) = arr(i, 1)
If IsNumeric(arr(i, 2)) And arr(i, 2) > удалённоеЧисло Then newArr(outIndex, 2) = arr(i, 2) - 1 Else newArr(outIndex, 2) = arr(i, 2) End If
outIndex = outIndex + 1 End If
Next i
.Range("C2:D" & lastRow).ClearContents .Range("C2").Resize(UBound(newArr, 1), 2).Value = newArr End With
восстановить = False
CleanExit:
With Application .Calculation = xlCalculationManual .EnableEvents = True .DisplayAlerts = True .ScreenUpdating = True End With Exit Sub
ErrorHandler:
If восстановить Then
With ThisWorkbook.Worksheets("Лист1") .Range("C2:D" & lastRow).ClearContents .Range("C2").Resize(UBound(arr, 1), 2).Value = arr End With
MsgBox "Произошла ошибка: " & Err.Description & vbCrLf & "Данные были восстановлены.", vbCritical Else MsgBox "Произошла ошибка: " & Err.Description, vbCritical End If
Resume CleanExit End Sub
[/vba]
Суть такова кода: Ставновитесь на ячейку в любой колонке (C:D), запускаете макрос. Он сам удалит строку выбранную и пронумерует снова. Может чем поможет. Удачи.
Sub ОбновитьНумерациюПослеУдаления() Dim i As Long On Error GoTo ErrorHandler
With Application .ScreenUpdating = False .DisplayAlerts = False .EnableEvents = False .Calculation = xlCalculationManual End With
With ThisWorkbook.Worksheets("Лист1")
Dim lastRow As Long lastRow = .Cells(.Rows.Count, "C").End(xlUp).Row
If ActiveCell.Row < 2 Or ActiveCell.Row > lastRow Then MsgBox "Выберите строку в диапазоне данных!", vbExclamation GoTo CleanExit End If
Dim arr As Variant arr = .Range("C2:D" & lastRow).Value
Dim восстановить As Boolean восстановить = True
Dim удаляемаяСтрока As Long удаляемаяСтрока = ActiveCell.Row - 1
Dim удалённоеЧисло As Long удалённоеЧисло = arr(удаляемаяСтрока, 2)
Dim newArr() As Variant ReDim newArr(1 To UBound(arr, 1) - 1, 1 To 2)
Dim outIndex As Long outIndex = 1
For i = 1 To UBound(arr, 1)
If i <> удаляемаяСтрока Then newArr(outIndex, 1) = arr(i, 1)
If IsNumeric(arr(i, 2)) And arr(i, 2) > удалённоеЧисло Then newArr(outIndex, 2) = arr(i, 2) - 1 Else newArr(outIndex, 2) = arr(i, 2) End If
outIndex = outIndex + 1 End If
Next i
.Range("C2:D" & lastRow).ClearContents .Range("C2").Resize(UBound(newArr, 1), 2).Value = newArr End With
восстановить = False
CleanExit:
With Application .Calculation = xlCalculationManual .EnableEvents = True .DisplayAlerts = True .ScreenUpdating = True End With Exit Sub
ErrorHandler:
If восстановить Then
With ThisWorkbook.Worksheets("Лист1") .Range("C2:D" & lastRow).ClearContents .Range("C2").Resize(UBound(arr, 1), 2).Value = arr End With
MsgBox "Произошла ошибка: " & Err.Description & vbCrLf & "Данные были восстановлены.", vbCritical Else MsgBox "Произошла ошибка: " & Err.Description, vbCritical End If
Resume CleanExit End Sub
[/vba]
Суть такова кода: Ставновитесь на ячейку в любой колонке (C:D), запускаете макрос. Он сам удалит строку выбранную и пронумерует снова. Может чем поможет. Удачи.MikeVol
Ученик. Одесса - Украина
Сообщение отредактировал MikeVol - Понедельник, 14.07.2025, 18:44
Уважаемый MikeVol, большое Вам спасибо. Вы все правильно поняли, работает.
[moder]Если Вам помогли и Вы хотите сказать "Спасибо" форумчанину помогшему Вам - нажмите "+" напротив надписи "Репутация" в любом его посте.[/moder]
Уважаемый MikeVol, большое Вам спасибо. Вы все правильно поняли, работает.
[moder]Если Вам помогли и Вы хотите сказать "Спасибо" форумчанину помогшему Вам - нажмите "+" напротив надписи "Репутация" в любом его посте.[/moder]Egider
Уважаемый MikeVol, извиняюсь, но если необходимо удалять всю строку, а не две соседние ячейки, то какие изменения необходимо произвести? Изменить только диапазон или еще что?
Уважаемый MikeVol, извиняюсь, но если необходимо удалять всю строку, а не две соседние ячейки, то какие изменения необходимо произвести? Изменить только диапазон или еще что?Egider
Необходимо знать границы диапазона вашей таблицы. Не зная границ таблицы могу предложить вариант изменить пару строк в коде:
[vba]
Код
Option Explicit
Sub ОбновитьНумерациюПослеУдаления_v2() Dim i As Long On Error GoTo ErrorHandler
With Application .ScreenUpdating = False .DisplayAlerts = False .EnableEvents = False .Calculation = xlCalculationManual End With
With ThisWorkbook.Worksheets("Лист1")
Dim lastRow As Long lastRow = .Cells(.Rows.Count, "C").End(xlUp).Row
If ActiveCell.Row < 2 Or ActiveCell.Row > lastRow Then MsgBox "Выберите строку в диапазоне данных!", vbExclamation GoTo CleanExit End If
Dim arr As Variant arr = .Range("C2:D" & lastRow).Value
Dim восстановить As Boolean восстановить = True
Dim удаляемаяСтрока As Long удаляемаяСтрока = ActiveCell.Row - 1
Dim удалённоеЧисло As Long удалённоеЧисло = arr(удаляемаяСтрока, 2)
Dim newArr() As Variant ReDim newArr(1 To UBound(arr, 1) - 1, 1 To 2)
Dim outIndex As Long outIndex = 1
For i = 1 To UBound(arr, 1)
If i <> удаляемаяСтрока Then newArr(outIndex, 1) = arr(i, 1)
If IsNumeric(arr(i, 2)) And arr(i, 2) > удалённоеЧисло Then newArr(outIndex, 2) = arr(i, 2) - 1 Else newArr(outIndex, 2) = arr(i, 2) End If
outIndex = outIndex + 1 End If
Next i
.Rows(ActiveCell.Row).ClearContents ' .Range("C2:D" & lastRow).ClearContents .Range("C2").Resize(UBound(newArr, 1), 2).Value = newArr End With
восстановить = False
CleanExit:
With Application .Calculation = xlCalculationAutomatic .EnableEvents = True .DisplayAlerts = True .ScreenUpdating = True End With Exit Sub
ErrorHandler:
If восстановить Then
With ThisWorkbook.Worksheets("Лист1") .Range("C2:D" & lastRow).ClearContents .Range("C2").Resize(UBound(arr, 1), 2).Value = arr End With
MsgBox "Произошла ошибка: " & Err.Description & vbCrLf & "Данные были восстановлены.", vbCritical Else MsgBox "Произошла ошибка: " & Err.Description, vbCritical End If
Resume CleanExit End Sub
[/vba]
Но данный код затронет целиком всю строку, что не есть хорошо если у вас правее вашей таблицы есть ещё какие-то данные. Он очистит и те данные. Будьте аккуратнее или дайте пример файла где будет виден ваш диапазон. Удачи.
Необходимо знать границы диапазона вашей таблицы. Не зная границ таблицы могу предложить вариант изменить пару строк в коде:
[vba]
Код
Option Explicit
Sub ОбновитьНумерациюПослеУдаления_v2() Dim i As Long On Error GoTo ErrorHandler
With Application .ScreenUpdating = False .DisplayAlerts = False .EnableEvents = False .Calculation = xlCalculationManual End With
With ThisWorkbook.Worksheets("Лист1")
Dim lastRow As Long lastRow = .Cells(.Rows.Count, "C").End(xlUp).Row
If ActiveCell.Row < 2 Or ActiveCell.Row > lastRow Then MsgBox "Выберите строку в диапазоне данных!", vbExclamation GoTo CleanExit End If
Dim arr As Variant arr = .Range("C2:D" & lastRow).Value
Dim восстановить As Boolean восстановить = True
Dim удаляемаяСтрока As Long удаляемаяСтрока = ActiveCell.Row - 1
Dim удалённоеЧисло As Long удалённоеЧисло = arr(удаляемаяСтрока, 2)
Dim newArr() As Variant ReDim newArr(1 To UBound(arr, 1) - 1, 1 To 2)
Dim outIndex As Long outIndex = 1
For i = 1 To UBound(arr, 1)
If i <> удаляемаяСтрока Then newArr(outIndex, 1) = arr(i, 1)
If IsNumeric(arr(i, 2)) And arr(i, 2) > удалённоеЧисло Then newArr(outIndex, 2) = arr(i, 2) - 1 Else newArr(outIndex, 2) = arr(i, 2) End If
outIndex = outIndex + 1 End If
Next i
.Rows(ActiveCell.Row).ClearContents ' .Range("C2:D" & lastRow).ClearContents .Range("C2").Resize(UBound(newArr, 1), 2).Value = newArr End With
восстановить = False
CleanExit:
With Application .Calculation = xlCalculationAutomatic .EnableEvents = True .DisplayAlerts = True .ScreenUpdating = True End With Exit Sub
ErrorHandler:
If восстановить Then
With ThisWorkbook.Worksheets("Лист1") .Range("C2:D" & lastRow).ClearContents .Range("C2").Resize(UBound(arr, 1), 2).Value = arr End With
MsgBox "Произошла ошибка: " & Err.Description & vbCrLf & "Данные были восстановлены.", vbCritical Else MsgBox "Произошла ошибка: " & Err.Description, vbCritical End If
Resume CleanExit End Sub
[/vba]
Но данный код затронет целиком всю строку, что не есть хорошо если у вас правее вашей таблицы есть ещё какие-то данные. Он очистит и те данные. Будьте аккуратнее или дайте пример файла где будет виден ваш диапазон. Удачи.MikeVol
Ученик. Одесса - Украина
Сообщение отредактировал MikeVol - Среда, 16.07.2025, 00:59
Уважаемый MikeVol, используя Ваши данные хотел внести изменения в таблицу. Но не получается, не могу добиться желаемого. Поэтому прошу еще раз взглянуть на мою таблицу и подсказать, можно ли сделать так, чтобы нумерация сохранялась даже если она идет не по порядку. Нужно чтобы после удаления строки нумерация сохранялась не нарушая порядка расположения строк после сортировки. В прилагаемом файле указаны границы таблицы "А4:АВ". Вариант 1 подходит, но нужно изменить диапазон и добиться удаления выбранной в колонке АВ строки.
Уважаемый MikeVol, используя Ваши данные хотел внести изменения в таблицу. Но не получается, не могу добиться желаемого. Поэтому прошу еще раз взглянуть на мою таблицу и подсказать, можно ли сделать так, чтобы нумерация сохранялась даже если она идет не по порядку. Нужно чтобы после удаления строки нумерация сохранялась не нарушая порядка расположения строк после сортировки. В прилагаемом файле указаны границы таблицы "А4:АВ". Вариант 1 подходит, но нужно изменить диапазон и добиться удаления выбранной в колонке АВ строки.Egider
Sub u_127() Application.ScreenUpdating = False a = Cells(Rows.Count, "d").End(xlUp).Row Dim arr() For b = 4 To a c = Evaluate("MATCH(" & Range("d" & b).Value & ",SMALL(D4:D" & a & ",ROW(D4:D" & a & ")-3),)") ReDim Preserve arr(b - 4) arr(b - 4) = c Next For d = 4 To a Range("d" & d) = arr(d - 4) Next Application.ScreenUpdating = True End Sub
[/vba]
вариант [vba]
Код
Sub u_127() Application.ScreenUpdating = False a = Cells(Rows.Count, "d").End(xlUp).Row Dim arr() For b = 4 To a c = Evaluate("MATCH(" & Range("d" & b).Value & ",SMALL(D4:D" & a & ",ROW(D4:D" & a & ")-3),)") ReDim Preserve arr(b - 4) arr(b - 4) = c Next For d = 4 To a Range("d" & d) = arr(d - 4) Next Application.ScreenUpdating = True End Sub
If Not IsEmpty(.Range("AA4")) Then targetRow = .Range("AA4").End(xlDown).Row + 1 If targetRow <= .Rows.Count Then .Range(.Cells(targetRow, 1), .Cells(targetRow, 28)).Delete End If
.Range("AB4").FormulaArray = "=Z4&Y4" .Range("AB4").AutoFill Destination:=.Range("AB4:AB" & Application.Max(4, .Cells(.Rows.Count, "AA").End(xlUp).Row)) End With
восстановить = False
CleanExit:
With Application .Calculation = xlCalculationAutomatic .EnableEvents = True .DisplayAlerts = True .ScreenUpdating = True End With Exit Sub
If Not IsEmpty(.Range("AA4")) Then targetRow = .Range("AA4").End(xlDown).Row + 1 If targetRow <= .Rows.Count Then .Range(.Cells(targetRow, 1), .Cells(targetRow, 28)).Delete End If
.Range("AB4").FormulaArray = "=Z4&Y4" .Range("AB4").AutoFill Destination:=.Range("AB4:AB" & Application.Max(4, .Cells(.Rows.Count, "AA").End(xlUp).Row)) End With
MsgBox "Произошла ошибка: " & Err.Description & vbCrLf & "Данные были восстановлены.", vbCritical Else MsgBox "Произошла ошибка: " & Err.Description, vbCritical End If
Resume CleanExit End Sub
[/vba]
Логика таже, становитесь на ячейку в диапазоне A4:AB и запускаете макрос. Удачи.
Egider, Может кто сможет оптимальнее но как умею:
[vba]
Код
Option Explicit
Sub Вариант3() Dim i As Long, targetRow As Long On Error GoTo ErrorHandler
With Application .ScreenUpdating = False .DisplayAlerts = False .EnableEvents = False .Calculation = xlCalculationManual End With
With ThisWorkbook.Worksheets("Лист1")
Dim lastRow As Long lastRow = .Cells(.Rows.Count, "AB").End(xlUp).Row
If ActiveCell.Row < 4 Or ActiveCell.Row > lastRow Then MsgBox "Выберите строку в диапазоне данных!", vbExclamation GoTo CleanExit End If
Dim arr As Variant arr = .Range("A4:AB" & lastRow).Value
Dim восстановить As Boolean восстановить = True
Dim удаляемаяСтрока As Long удаляемаяСтрока = ActiveCell.Row - 3
Dim удалённоеЧисло As Long удалённоеЧисло = arr(удаляемаяСтрока, 27)
Dim newArr() As Variant ReDim newArr(1 To UBound(arr, 1) - 1, 1 To UBound(arr, 2))
Dim outIndex As Long outIndex = 1
For i = 1 To UBound(arr, 1)
If i <> удаляемаяСтрока Then Dim j As Long
For j = 1 To UBound(arr, 2) newArr(outIndex, j) = arr(i, j) Next j
If IsNumeric(arr(i, 27)) Then
If arr(i, 27) > удалённоеЧисло Then newArr(outIndex, 27) = arr(i, 27) - 1 Else newArr(outIndex, 27) = arr(i, 27) End If
If Not IsEmpty(.Range("AA4")) Then targetRow = .Range("AA4").End(xlDown).Row + 1 If targetRow <= .Rows.Count Then .Range(.Cells(targetRow, 1), .Cells(targetRow, 28)).Delete End If
.Range("AB4").FormulaArray = "=Z4&Y4" .Range("AB4").AutoFill Destination:=.Range("AB4:AB" & Application.Max(4, .Cells(.Rows.Count, "AA").End(xlUp).Row)) End With
восстановить = False
CleanExit:
With Application .Calculation = xlCalculationAutomatic .EnableEvents = True .DisplayAlerts = True .ScreenUpdating = True End With Exit Sub
If Not IsEmpty(.Range("AA4")) Then targetRow = .Range("AA4").End(xlDown).Row + 1 If targetRow <= .Rows.Count Then .Range(.Cells(targetRow, 1), .Cells(targetRow, 28)).Delete End If
.Range("AB4").FormulaArray = "=Z4&Y4" .Range("AB4").AutoFill Destination:=.Range("AB4:AB" & Application.Max(4, .Cells(.Rows.Count, "AA").End(xlUp).Row)) End With
MsgBox "Произошла ошибка: " & Err.Description & vbCrLf & "Данные были восстановлены.", vbCritical Else MsgBox "Произошла ошибка: " & Err.Description, vbCritical End If
Resume CleanExit End Sub
[/vba]
Логика таже, становитесь на ячейку в диапазоне A4:AB и запускаете макрос. Удачи.MikeVol
Ученик. Одесса - Украина
Сообщение отредактировал MikeVol - Четверг, 17.07.2025, 00:00
Уважаемые форумчане, уважаемый MikeVol, помогите решить эту задачу: почему после нажатия коммандбутон6 на юзерформе и исполнении команды на нумерацию строк в Екселе, не закрывается сама форма?
Уважаемые форумчане, уважаемый MikeVol, помогите решить эту задачу: почему после нажатия коммандбутон6 на юзерформе и исполнении команды на нумерацию строк в Екселе, не закрывается сама форма?Egider
Пенсионер
Сообщение отредактировал Egider - Воскресенье, 20.07.2025, 00:46
If Not IsEmpty(.Range("X4")) Then targetRow = .Range("X4").End(xlDown).Row + 1 If targetRow <= .Rows.Count Then .Range(.Cells(targetRow, 1), .Cells(targetRow, 25)).Delete End If
.Range("Y4").FormulaArray = "=W4&L4&U4" .Range("Y4").AutoFill Destination:=.Range("Y4:Y" & Application.Max(4, .Cells(.Rows.Count, "X").End(xlUp).Row)) End With
восстановить = False
CleanExit:
With Application .Calculation = xlCalculationAutomatic .EnableEvents = True .DisplayAlerts = True .ScreenUpdating = True End With Exit Sub
If Not IsEmpty(.Range("X4")) Then targetRow = .Range("X4").End(xlDown).Row + 1 If targetRow <= .Rows.Count Then .Range(.Cells(targetRow, 1), .Cells(targetRow, 25)).Delete End If
.Range("Y4").FormulaArray = "=W4&L4&U4" .Range("Y4").AutoFill Destination:=.Range("Y4:Y" & Application.Max(4, .Cells(.Rows.Count, "X").End(xlUp).Row)) End With
MsgBox "Произошла ошибка: " & Err.Description & vbCrLf & "Данные были восстановлены.", vbCritical Else MsgBox "Произошла ошибка: " & Err.Description, vbCritical End If
Resume CleanExit UserForm1.Hide Unload Me End Sub
[/vba] Почему не закрывается юзерформа? Не могу понять
[vba]
Код
Option Explicit Private Sub CommandButton6_Click() Dim i As Long, targetRow As Long On Error GoTo ErrorHandler
With Application .ScreenUpdating = False .DisplayAlerts = False .EnableEvents = False .Calculation = xlCalculationManual End With
With ThisWorkbook.Worksheets("Лист1")
Dim lastRow As Long lastRow = .Cells(.Rows.Count, "Y").End(xlUp).Row
If ActiveCell.Row < 4 Or ActiveCell.Row > lastRow Then MsgBox "Выберите строку в диапазоне данных!", vbExclamation GoTo CleanExit End If
Dim arr As Variant arr = .Range("A4:Y" & lastRow).Value
Dim восстановить As Boolean восстановить = True
Dim удаляемаяСтрока As Long удаляемаяСтрока = ActiveCell.Row - 3
Dim удалённоеЧисло As Long удалённоеЧисло = arr(удаляемаяСтрока, 24)
Dim newArr() As Variant ReDim newArr(1 To UBound(arr, 1) - 1, 1 To UBound(arr, 2)) ' ReDim newArr(1 To UBound(arr, 1) - 1, 1 To 2)
Dim outIndex As Long outIndex = 1
For i = 1 To UBound(arr, 1)
If i <> удаляемаяСтрока Then Dim j As Long
For j = 1 To UBound(arr, 2) newArr(outIndex, j) = arr(i, j) Next j
If IsNumeric(arr(i, 24)) And arr(i, 24) > удалённоеЧисло Then newArr(outIndex, 24) = arr(i, 24) - 1 End If
If Not IsEmpty(.Range("X4")) Then targetRow = .Range("X4").End(xlDown).Row + 1 If targetRow <= .Rows.Count Then .Range(.Cells(targetRow, 1), .Cells(targetRow, 25)).Delete End If
.Range("Y4").FormulaArray = "=W4&L4&U4" .Range("Y4").AutoFill Destination:=.Range("Y4:Y" & Application.Max(4, .Cells(.Rows.Count, "X").End(xlUp).Row)) End With
восстановить = False
CleanExit:
With Application .Calculation = xlCalculationAutomatic .EnableEvents = True .DisplayAlerts = True .ScreenUpdating = True End With Exit Sub
If Not IsEmpty(.Range("X4")) Then targetRow = .Range("X4").End(xlDown).Row + 1 If targetRow <= .Rows.Count Then .Range(.Cells(targetRow, 1), .Cells(targetRow, 25)).Delete End If
.Range("Y4").FormulaArray = "=W4&L4&U4" .Range("Y4").AutoFill Destination:=.Range("Y4:Y" & Application.Max(4, .Cells(.Rows.Count, "X").End(xlUp).Row)) End With
MsgBox "Произошла ошибка: " & Err.Description & vbCrLf & "Данные были восстановлены.", vbCritical Else MsgBox "Произошла ошибка: " & Err.Description, vbCritical End If
Resume CleanExit UserForm1.Hide Unload Me End Sub
[/vba] Почему не закрывается юзерформа? Не могу понятьEgider
Пенсионер
Сообщение отредактировал Egider - Воскресенье, 20.07.2025, 00:48