Загрузка данных
' ===== В САМОМ ВЕРХУ МОДУЛЯ (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
Dim multiPart As Boolean
Dim parts As Variant
Dim cell2Text As String, cell3Text As String
' 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. Проверяем, есть ли табуляции (несколько ячеек)
multiPart = (InStr(clipText, vbTab) > 0)
cell2Text = ""
cell3Text = ""
If multiPart Then
Dim tableRows As Variant
tableRows = Split(clipText, vbCrLf)
If UBound(tableRows) < 0 Then tableRows = Split(clipText, vbLf)
' Ищем первую непустую строку
Dim rowText As String
rowText = ""
For i = 0 To UBound(tableRows)
If Trim(tableRows(i)) <> "" Then
rowText = tableRows(i)
Exit For
End If
Next i
' Разбиваем строку по табуляции
parts = Split(rowText, vbTab)
If UBound(parts) >= 2 Then
cell2Text = parts(1)
If UBound(parts) >= 3 Then
cell3Text = parts(2)
End If
' Первая часть – убираем пустые строки
clipText = parts(0)
End If
End If
' 3. Очищаем от пустых строк с помощью Collection (безопасно)
Dim rawLines As Variant
rawLines = Split(clipText, vbCrLf)
If UBound(rawLines) < 0 Then rawLines = Split(clipText, vbLf)
Dim colLines As New Collection
Dim rawLine As Variant
For Each rawLine In rawLines
If Trim(CStr(rawLine)) <> "" Then
colLines.Add CStr(rawLine)
End If
Next rawLine
If colLines.Count = 0 Then
MsgBox "Не найдено ни одной строки текста.", vbInformation
Exit Sub
End If
' Переносим в массив linesArr
numLines = colLines.Count
ReDim linesArr(0 To numLines - 1)
For i = 1 To numLines
linesArr(i - 1) = colLines(i)
Next i
' 4. Сохраняем состояние ячеек, которые будут затёрты
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
' 5. Вставляем строки (сдвиг вниз) и заполняем
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
' Если есть вторая/третья ячейка – заполняем на каждой строке
If multiPart Then
ws.Cells(SavedRow + i, 5).Value = cell2Text ' столбец E
ws.Cells(SavedRow + i, 5).Font.Bold = False
ws.Cells(SavedRow + i, 6).Value = cell3Text ' столбец F
ws.Cells(SavedRow + i, 6).Font.Bold = False
End If
Next i
' 6. Автоподбор высоты строк
ws.Rows(SavedRow & ":" & SavedRow + numLines - 1).EntireRow.AutoFit
' 7. Удаление всех строк до следующей объединённой ячейки в столбцах C или D
Dim lastInsertedRow As Long
lastInsertedRow = SavedRow + numLines - 1
Dim nextMergedRow As Long
nextMergedRow = 0
Dim r As Long
For r = lastInsertedRow + 1 To lastInsertedRow + 1000
If ws.Cells(r, 3).MergeCells Or ws.Cells(r, 4).MergeCells Then
If ws.Cells(r, 3).MergeCells Then
nextMergedRow = ws.Cells(r, 3).MergeArea.Row
Else
nextMergedRow = ws.Cells(r, 4).MergeArea.Row
End If
Exit For
End If
Next r
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
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