Я пытаюсь повторить следующий метод в C# Word Interop (NetOffice)
Selection.PasteSpecial Link:=True, DataType:=wdPasteMetafilePicture, _
Placement:=wdInLine, DisplayAsIcon:=False
Я говорю «реплицировать», так как я не хочу на самом деле использовать метод PasteSpecial
, так как мне нужно обновить field
типа link
в одном go, и я не люблю общаться с Excel, полагаясь на копирование и вставку.
У меня уже есть следующий код, который выполняет в основном то, что я хочу, но есть некоторые проблемы, которые я не могу решить.
Selection.InlineShapes.AddOLEObject ("Excel.Sheet.12", fileName + $"!{label}", true)
Этот метод завершается ошибкой с сообщением об ошибке
Word не может создать ссылку на объект, который вы указали. Пожалуйста, вставьте объект непосредственно в ваш файл, не создавая ссылку
Я получаю это сообщение об ошибке только в том случае, если я использую сетевой диск или путь c с меткой. например.
T:\TestFile.xlsx!Sheet1!TestRange
T:\TestFile.xlsx!Sheet1!R1C1:R2C2
//notice that T is a network drive and not a local drive
\\TestShare\TestFile.xlsx!Sheet1!TestRange
\\TestShare\TestFile.xlsx!Sheet1!R1C1:R2C2
Если я не использую ярлык, например.
T:\TestFile.xlsx
T:\TestFile.xlsx
//notice that T is a network drive and not a local drive
\\TestShare\TestFile.xlsx
\\TestShare\TestFile.xlsx
или локальный диск, например. C: (с меткой или без)
C:\TestFile.xlsx
C:\TestFile.xlsx
C:\TestFile.xlsx!Sheet1!TestRange
C:\TestFile.xlsx!Sheet1!R1C1:R2C2
все работает нормально.
Таким образом, только комбинированный сетевой диск или un c + метка выдают это сообщение об ошибке.
Я подумал, ладно, нет проблем, я уже знаю, как изменить путь и метку производимого field
, и написал следующий код для включения метки во второй шаг.
var inlineShape = Selection.InlineShapes.AddOLEObject("Excel.Sheet.12", fileName, true);
field = inlineShape.Field;
if (!string.IsNullOrEmpty(label))
{
var fieldCode = field.Code.Text;
//replace the produced empty label "" with the label I desire eg. "Sheet1!R1C1:R2C2"
fieldCode = fieldCode.Replace(" \"\" ", $" \"{label}\"");
//write the updated fieldcode back to the field
field.Code.Text = fieldCode;
//update the field
field.Update();
}
НО это решение меняет базовый формат изображения с WMF (Windows Meta File) на EMF (Enhanced Meta File), но мне нужно, чтобы он был сохранен в формате WMF, так как Office 2010
неправильно отображает EMF .
Чтобы получить базовый файл, я переименовываю свой docx
в zip
и извлекаю его, чтобы посмотреть в каталог word\media
.
PasteSpecial
не выдает эту ошибку и создает желаемый формат WMF, но я не могу на 100% повторить процедуру, которая происходит, пока PasteSpecial
.
Как я отмечаю, я не хочу иметь png
или bmp
либо, так как они генерируются с размытостью вокруг шрифта, поэтому лучше всего Sult обеспечивает wmf
для Office 2010
.
Для Office 2013
и выше, я использую следующий код для получения emf
с самого начала и не сталкиваюсь с проблемой сетевого диска / un c + ошибка метки.
var field = range.Fields.Add(range, WdEnums.WdFieldType.wdFieldLink);
field.LinkFormat.SourceFullName = fileName + $"!{label}";
Редактировать:
Вот скриншот основной проблемы, которую я пытаюсь решить, напоминая вот как это выглядит в Office 2010
в Office 2013
и выше оба выглядят прилично:
Для обоих я использую специальную пасту https://support.office.com/en-us/article/paste-special-e03db6c7-8295-4529-957d-16ac8a778719
Первая таблица в Word-документ создает файл EMF. При использовании специального формата вставки «Рисунок (расширенный метафайл)» при записи макросов получается следующий код:
Selection.PasteSpecial Link:=False, DataType:=wdPasteEnhancedMetafile, _
Placement:=wdInLine, DisplayAsIcon:=False
Вторая таблица в документе Word создает файл WMF при использовании специальный формат вставки «Picture (Windows Metafile)», запись макроса производит этот код:
Selection.PasteSpecial Link:=True, DataType:=wdPasteMetafilePicture, _
Placement:=wdInLine, DisplayAsIcon:=False
На правой стороне вы можете увидеть файл Excel, который я скопировал, чтобы вставить в левое слово документа .
Как вы можете ясно видеть, Office 2010
рендерит / др aws файл WMF le (вторая таблица в текстовом документе) намного лучше, так что это был бы мой желаемый результат, но, как я уже упоминал, у меня есть проблемы с копированием PasteSpecial
и сохранением файла WMF
, который делает / dr aws лучше.
Edit2:
Я записал свой экран, чтобы показать ошибку, пожалуйста, извините, что моя среда на немецком языке. https://imgur.com/a/50wcBGQ
Я использовал следующий код:
Sub NetworkAndLabel()
'this will fail
Dim fileName As String
Dim label As String
'T is a mapped drive for the share \\NAS1\Ablage
fileName = "T:\rfa\TestFile.xlsx"
'label is in german, in english it would be Sheet1!R1C1:R1C2
label = "Tabelle1!Z1S1:Z2S2"
Selection.InlineShapes.AddOLEObject "Excel.Sheet.12", fileName & "!" & label, True
End Sub
Sub Network()
'this will run successfully
Dim fileName As String
Dim label As String
'T is a mapped drive for the share \\NAS1\Ablage
fileName = "T:\rfa\TestFile.xlsx"
Selection.InlineShapes.AddOLEObject "Excel.Sheet.12", fileName, True
End Sub
Sub LocalAndLabel()
'this will run successfully
Dim fileName As String
Dim label As String
'E is a local drive (second partition, not a seperate drive)
'up till now, I only tested with C and wanted to see if a simple second partition works or not
fileName = "E:\rfa\TestFile.xlsx"
'label is in german, in english it would be Sheet1!R1C1:R1C2
label = "Tabelle1!Z1S1:Z2S2"
Selection.InlineShapes.AddOLEObject "Excel.Sheet.12", fileName & "!" & label, True
End Sub
Sub Local_()
'this will run successfully
Dim fileName As String
Dim label As String
'E is a local drive (second partition, not a seperate drive)
'up till now, I only tested with C and wanted to see if a simple second partition works or not
fileName = "E:\rfa\TestFile.xlsx"
Selection.InlineShapes.AddOLEObject "Excel.Sheet.12", fileName, True
End Sub
Я написал "UsedRange" в C5
файла Excel, чтобы показать разницу вывод в слове, если метка используется или не используется, если я не указываю метку, она использует UsedRange
первого листа.
К вашему сведению, я написал код простым vba
, чтобы продемонстрировать, что он не имеет ничего общего с C#
и может воспроизводиться без особого особенного воспроизведения. В конце концов решение, если оно есть, будет включено в мое приложение C#
.
Edit3:
Просто чтобы уточнить, если кто-то знает способ улучшить Office 2010
рендеринг / отрисовку файла EMF
, это также будет правильным решением для моей проблемы, потому что в конце дня я просто хочу иметь прилично выглядящий связанный файл Excel в моем текстовом документе. Мне все равно, если EMF
или WMF
, я просто пытаюсь работать с WMF
, потому что он выглядит лучше, и у меня есть проблемы, которые я описал, говорящие Office 2010
, чтобы остаться в формате WMF
.
Поскольку я знаю, что единственный способ преодолеть сообщение об ошибке - это манипулировать Field
, как показано выше, но после вызова field.Update()
файл WMF
заменяется на EMF
, и в результате я получаю плохо выглядящий файл рендеринга / отрисовки EMF
файла.
Edit4:
В соответствии с просьбой я посмотрел в Внутренняя структура документа и взглянул на различия. Фактическая разница, в основном, равна 0, есть только вещи, которые должны быть необратимыми, такие как номер редакции, количество символов и тому подобное.
Но я заметил следующее, хотя этот код
Selection.PasteSpecial Link:=True, DataType:=wdPasteMetafilePicture, _
Placement:=wdInLine, DisplayAsIcon:=False
генерирует файл WMF
, который я могу увидеть, заглянув в папку word\media
и увидев там созданный image1.wmf
, или просмотрев файл word\_rels\document.xml.rels
, который имеет следующую запись
<Relationship Id="rId7" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/image" Target="media/image1.wmf"/>
Фактический XML
для объекта OLE имеет следующее значение в word\document.xml
<o:OLEObject Type="Link" ProgID="Excel.Sheet.12" ShapeID="_x0000_i1025" DrawAspect="Content" r:id="rId8" UpdateMode="Always"><o:LinkType>EnhancedMetaFile</o:LinkType><o:LockedField>false</o:LockedField></o:OLEObject>
Как вы можете видеть, LinkType
определяется как EnhancedMetaFile
(EMF).
Поскольку объект OLE определен следующим образом, я попытался, если простой вызов field.Update
вызовет изменение с WMF
на EMF
, и, к сожалению, так и есть, так что даже без меня модифицируя field
код, простой вызов, подобный этому
Selection.InlineShapes(1).Field.Update
уже будет запускать преобразование из WMF
в EMF
, поскольку объект OLE просто определяется следующим образом, преобразование также можно выполнить без какого-либо специального кода просто выберите встроенную форму и нажмите F9
или щелкните правой кнопкой мыши и выберите Update Links
(перевод из моей немецкой среды)
Обратите внимание, что по какой-либо причине этот код
Selection.InlineShapes.AddOLEObject("Excel.Sheet.12", "E:\rfa\TestFile.xlsx", True).Field.Update
не сработает преобразование, но если вы сохраните слово document и снова откроете его, то вы можете вызвать field.Update
, чтобы вызвать преобразование.
Таким образом, чтобы преобразование было одним go, без необходимости сохранения / закрывая слово document, вам нужно как минимум назвать это
With Selection.InlineShapes.AddOLEObject("Excel.Sheet.12", "E:\rfa\TestFile.xlsx!Tabelle1!Z1S1:Z2S2", True).Field
.Code.Text = Replace(.Code.Text, "Z1S1:Z2S2", "Z2S2:Z3S3")
.Update
End With