Загрузка данных
' ===== В САМОМ ВЕРХУ МОДУЛЯ (Personal.xlsb) =====
Private SavedRow As Long
Private SavedCol As Long
Private SavedNumLines As Long
Private SavedOldData As Variant
' =================================================
Sub ВставитьСписокИзWordСНумерацией()
Dim dataObj As Object, clipText As String, linesArr As Variant
Dim i As Long, lineText As String, numPart As String, textPart As String
Dim dotPos As Long, numLines As Long
Dim ws As Worksheet
Dim rngBefore As Range
' 1. Читаем буфер обмена
On Error Resume Next
Set dataObj = CreateObject("New:{1C3B4210-F441-11CE-B9EA-00AA006B1A69}")
If Err.Number <> 0 Then
On Error GoTo 0
Set dataObj = CreateObject("MSForms.DataObject")
End If
On Error GoTo 0
If dataObj Is Nothing Then
MsgBox "Не удалось получить доступ к буферу обмена.", vbExclamation
Exit Sub
End If
dataObj.GetFromClipboard
clipText = dataObj.GetText
If Len(Trim(clipText)) = 0 Then
MsgBox "Буфер обмена пуст или содержит не текст.", vbInformation
Exit Sub
End If
' 2. Разбиваем на строки
linesArr = Split(clipText, vbCrLf)
If UBound(linesArr) < 0 Then linesArr = Split(clipText, vbLf)
numLines = UBound(linesArr) + 1
If numLines > 0 Then
If Len(Trim(linesArr(numLines - 1))) = 0 Then numLines = numLines - 1
End If
If numLines = 0 Then
MsgBox "Не найдено ни одной строки текста.", vbInformation
Exit Sub
End If
' 3. Сохраняем состояние ячеек, которые будут затёрты
Set ws = ActiveSheet
SavedRow = ActiveCell.Row
SavedCol = ActiveCell.Column
SavedNumLines = numLines
Set rngBefore = ws.Range(ws.Cells(SavedRow, SavedCol), ws.Cells(SavedRow + numLines - 1, SavedCol + 1))
If Not rngBefore Is Nothing Then
SavedOldData = rngBefore.Value
Else
SavedOldData = Empty
End If
' 4. Вставляем строки (сдвиг вниз) и заполняем
Application.ScreenUpdating = False
ws.Rows(SavedRow & ":" & SavedRow + numLines - 1).Insert Shift:=xlDown, CopyOrigin:=xlFormatFromLeftOrAbove
For i = 0 To numLines - 1
lineText = linesArr(i)
dotPos = InStr(lineText, ". ")
If dotPos > 0 And IsNumeric(Left(lineText, dotPos - 1)) Then
numPart = Left(lineText, dotPos + 1) ' "1. "
textPart = Trim(Mid(lineText, dotPos + 2))
Else
numPart = ""
textPart = lineText
End If
With ws.Cells(SavedRow + i, SavedCol)
.Value = numPart
.Font.Bold = False
.HorizontalAlignment = xlRight
End With
With ws.Cells(SavedRow + i, SavedCol + 1)
.Value = textPart
.Font.Bold = False
End With
Next i
' 5. Автоподбор высоты строк
ws.Rows(SavedRow & ":" & SavedRow + numLines - 1).EntireRow.AutoFit
' 6. Записываем в столбец F (строка последнего элемента) количество скопированных строк
Dim targetCell As Range
Set targetCell = ws.Cells(SavedRow + numLines - 1, 6) ' столбец F
' Если ячейка объединена — пишем в верхнюю левую ячейку объединения, НЕ снимая его
If targetCell.MergeCells Then
Set targetCell = targetCell.MergeArea(1)
End If
With targetCell
.Value = numLines
.Font.Bold = False
End With
' 7. Удаление ВСЕХ строк ниже вставленных до начала следующей объединённой ячейки в C или D
Dim lastInsertedRow As Long
lastInsertedRow = SavedRow + numLines - 1
Dim nextMergedRow As Long
nextMergedRow = 0
' Перебираем все объединённые диапазоны листа
Dim ma As Range
For Each ma In ws.UsedRange.MergeAreas
' Проверяем, что объединение находится в столбце C (3) или D (4) и начинается после вставленных данных
If (ma.Column = 3 Or ma.Column = 4) And ma.Row > lastInsertedRow Then
' Нашли кандидата — запоминаем ближайший
If nextMergedRow = 0 Or ma.Row < nextMergedRow Then
nextMergedRow = ma.Row
End If
End If
Next ma
' Если нашли объединение ниже — удаляем все строки от lastInsertedRow+1 до nextMergedRow-1
If nextMergedRow > 0 Then
Dim firstRowToDelete As Long, lastRowToDelete As Long
firstRowToDelete = lastInsertedRow + 1
lastRowToDelete = nextMergedRow - 1
If lastRowToDelete >= firstRowToDelete Then
ws.Rows(firstRowToDelete & ":" & lastRowToDelete).Delete Shift:=xlUp
End If
Else
' Если объединение не найдено — ничего не удаляем (можно раскомментировать для диагностики)
' MsgBox "Не найдено объединённой ячейки в столбцах C или D ниже вставленных данных.", vbInformation
End If
Application.ScreenUpdating = True
End Sub
Sub ОтменитьПоследнююВставкуСписка()
If SavedNumLines <= 0 Then
MsgBox "Нет данных для отмены последней вставки.", vbInformation
Exit Sub
End If
Dim ws As Worksheet
Set ws = ActiveSheet
Application.ScreenUpdating = False
ws.Rows(SavedRow & ":" & SavedRow + SavedNumLines - 1).Delete Shift:=xlUp
If Not IsEmpty(SavedOldData) Then
Dim rngRestore As Range
Set rngRestore = ws.Range(ws.Cells(SavedRow, SavedCol), ws.Cells(SavedRow + SavedNumLines - 1, SavedCol + 1))
rngRestore.Value = SavedOldData
End If
SavedNumLines = 0
SavedOldData = Empty
Application.ScreenUpdating = True
End Sub