Как копировать вставить столбцы, настроить высоту ячеек с изображениями, не искажая изображения. (Excel VBA) - PullRequest
3 голосов
/ 19 марта 2019

Excel в качестве базы данных с изображениями в столбце:

Я хотел бы сделать инструмент, который позволяет на одном листе выбрать продукты, все необходимые расчеты скидок, а затем распечатать выбор как предложение для клиента. Таблица фильтруется, а затем видимые строки копируются в другую таблицу, готовую к печати. Один из столбцов содержит изображения. Изображения аккуратно прикреплены к ячейкам («двигайте, но НЕ размерьте с ячейками»)

  • Если я отфильтрую их, изображения не будут отфильтрованы, они будут наложены.
  • если после фильтрации я хочу скопировать их в другую таблицу, отформатированную для печати. Они приземляются в случайных местах, а не в клетках, где я бы хотел, чтобы они приземлились.

Существует ли решение для копирования и вставки изображений в формате Excel в том виде, в каком они есть, без изменения местоположения и размера (прикрепленных к ячейкам назначения с помощью VBA?

=== Что я пробовал:

  1. Пользователь фильтрует записи в таблице, которую он / она хотел бы включить в цитату.
  2. Нажатием кнопки он / она запускает макрос. Сначала он очищает все чертежи и данные в целевой таблице, в которую будут скопированы записи. Затем текст копируется отдельно, а изображения отдельно в целевые столбцы с кодом:

    с листами ("QuotationPrint")

        'copy descriptions
    
            Sheets("oferta stal").ListObjects("tblPricelist").ListColumns("Descriptions").DataBodyRange.SpecialCells(xlCellTypeVisible).Copy
            .Range("c8").PasteSpecial Paste:=xlPasteAllUsingSourceTheme ', SkipBlanks:=True
    
        'copy images
    
            Sheets("oferta stal").ListObjects("tblPricelist").ListColumns("images").DataBodyRange.SpecialCells(xlCellTypeVisible).Copy
            .Range("o8").Select
            ActiveSheet.Paste
    
            .Columns("H:I").Hidden = True
            .Range("n8:n300").SpecialCells(xlCellTypeBlanks).EntireRow.Hidden = True
            .Range("c8:c300").SpecialCells(xlCellTypeVisible).EntireRow.AutoFit
        End With
    

    На этом мои навыки заканчиваются. Что нужно сделать, чтобы избежать искажения копируемых изображений?

EDIT:

Пример данных будет содержать здесь два столбца (для упрощения) 1 Имя таблицы (listobject.table или таблица данных, созданная с помощью Ctrl + t) is 'tblPriceList.

Descriptions | images
------------------------
Lorem ipsum..| image1
Lorem muspi..| image2
meroL ipsum..| image3

Изображения вставляются и затем прикрепляются к ячейке с параметром «Переместить, но не изменять размер с ячейкой». Пользователь использует фильтр для выбора, скажем, строки 1 и 3, затем макрос копирует выбранные ячейки в новый пустой диапазон, начиная с ( О, 8) в другом листе. После вставки данных высота ячеек корректируется.

Вот воспроизводимый пример файла Excel, показывающий проблему. Данные сначала фильтруются пользователем. Изображения не фильтруются и копируются неправильно: https://drive.google.com/open?id=1bGXuB47dFqhp9wsYcuBTB7Se6gelPnok

1 Ответ

1 голос
/ 22 марта 2019

ОК, у меня здесь что-то работает:

Функция CopyVisible проходит по списку объектов и проверяет, видна ли строка, если это так, описание и все изображения пересекаются с ячейкой. Это происходит в правильном формате, если копировать более одной ячейки с изображением в нем, это запутано по неизвестной мне причине.

Option Explicit ' use this

Public Sub CopyVisible()
Dim SSheet As Worksheet ' Source
Dim TSheet As Worksheet  ' Target
Dim Scell As Range ' Target
Dim Tcell As Range 'Source
Dim Tbl As ListObject
Dim offset As Integer
Dim Pic As Shape
Dim Picrng As Range

Set TSheet = Worksheets("QuotationPrint")
Set SSheet = Worksheets("oferta stal")
Set Tbl = SSheet.ListObjects(1)

TSheet.Range("b8:o300").ClearContents  'remove everything below row 8
'Call DeletePicAll


Set Tcell = TSheet.Range("c8")

offset = 10 ' "from c8 to o8 the offset is 10

For Each Scell In Tbl.ListColumns(1).DataBodyRange  ' loop through table
    If IsVisible(Scell)(1, 1) Then ' only copy if visible

        'description
        Scell.Copy
        Tcell.PasteSpecial Paste:=xlPasteAllUsingSourceTheme ', SkipBlanks:=True
        Tcell.EntireRow.AutoFit

        'image
        For Each Pic In SSheet.Shapes
            Set Picrng = Range(Pic.TopLeftCell.Address & ":" & Pic.BottomRightCell.Address)
            If Not Intersect(Picrng, Scell.offset(0, 1)) Is Nothing Then
                Pic.Copy
                Tcell.offset(0, offset).PasteSpecial
            End If
        Next

    Set Tcell = Tcell.offset(1, 0)
    End If
Next Scell

End Sub

Эта функция была скопирована с Cpearson и помогает определить, видна ли ячейка или нет. Может также использоваться для диапазона.

Public Function IsVisible(InRange As Range) As Boolean()
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' IsVisible
' This function returns an array of Boolean values indicating whether the
' corresponding cell in InRange is visible.
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
    Dim R As Range
    Dim Arr() As Boolean
    Dim RNdx As Integer
    Dim CNdx As Integer

    ReDim Arr(1 To InRange.Rows.Count, 1 To InRange.Columns.Count)
    For RNdx = 1 To InRange.Rows.Count
        For CNdx = 1 To InRange.Columns.Count
            Set R = InRange(RNdx, CNdx)
            If R.EntireRow.Hidden = True Or R.EntireColumn.Hidden = True Then
                Arr(RNdx, CNdx) = False
            Else
                Arr(RNdx, CNdx) = True
            End If
        Next CNdx
    Next RNdx
    IsVisible = Arr
End Function

В целом проблема должна быть решена с этим. Несколько советов в конце: объявите свои переменные и заставьте себя сделать это, используя Option Explicit try , чтобы не использовать select и активировать , а если вы используете listobjects, используйте возможность циклически проходить по listrows listcolumns или databodyrange.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...