Как изменить таблицу Word в документе, встроенном в Excel

Обновление: теперь это добавлено в документацию для ?copy в версии 1.9.3. Из NEWS :
  1. Перемещено ?copy на свою страницу справки и задокументировано, что dt_names <- copy(names(DT)) необходимо, чтобы dt_names не был изменен ссылку в результате обновления DT по ссылке (например: добавление нового столбца по ссылке). Закрывает # 512 . Благодаря Zach для этот вопрос SO и user1971988 для этот вопрос SO .
blockquote>

Часть вашего первого вопрос делает для меня немного непонятным относительно того, что вы действительно имеете в виду относительно оператора <- (по крайней мере, в контексте data.table), особенно для части: . В других случаях мы явно предупреждают, что & lt; - создает копии, как data.tables, так и data.frames.

Итак, прежде чем отвечать на ваш реальный вопрос, я кратко коснусь его здесь. В случае data.table a <- (присвоение) просто недостаточно для копирования a data.table. Например:

DT <- data.table(x = 1:5, y= 6:10)
# assign DT2 to DT
DT2 <- DT # assign by reference, no copy taken.
DT2[, z := 11:15]
# DT will also have the z column

Если вы хотите создать copy, вы должны явно указать его с помощью команды copy.

DT2 <- copy(DT) # copied content to DT2
DT2[, z := 11:15] # only DT2 is affected

From CauchyDistributedRV, Я понимаю, что вы имеете в виду назначение names(dt) <- ., которое приведет к предупреждению. Я оставлю это как таковой.


Теперь, чтобы ответить на ваш первый вопрос: похоже, что names1 <- names(DT) также ведет себя аналогично. Я до сих пор не думал об этом. Здесь очень полезна команда .Internal(inspect(.)):

.Internal(inspect(names1))
# @7fc86a851480 16 STRSXP g0c7 [MARK,NAM(2)] (len=2, tl=100)
#   @7fc86a069f68 09 CHARSXP g1c1 [MARK,gp=0x61] [ASCII] [cached] "x"
#   @7fc86a0f96d8 09 CHARSXP g1c1 [MARK,gp=0x61] [ASCII] [cached] "y"

.Internal(inspect(names(DT)))
# @7fc86a851480 16 STRSXP g0c7 [MARK,NAM(2)] (len=2, tl=100)
#   @7fc86a069f68 09 CHARSXP g1c1 [MARK,gp=0x61] [ASCII] [cached] "x"
#   @7fc86a0f96d8 09 CHARSXP g1c1 [MARK,gp=0x61] [ASCII] [cached] "y"

Здесь вы видите, что они указывают на ту же ячейку памяти @7fc86a851480. Даже truelength из names1 равно 100 (по умолчанию выделено в data.table, для этого нужно проверить ?alloc.col.

truelength(names1)
# [1] 100

Таким образом, назначение names1 <- names(dt) кажется происходят по ссылке. То есть, names1 указывает на то же место, что и указатель имен столбца dt.

Чтобы ответить на ваш второй вопрос: команда c(.), похоже, создает копию , поскольку нет проверки того, что результат содержимого из-за операции конкатенации различен . То есть, поскольку операция c(.) может изменять содержимое вектора, это немедленно приводит к тому, что «копия» сделана без , проверяя, не изменяется ли содержимое.

0
задан Cindy Meister 15 January 2019 в 16:19
поделиться

1 ответ

Чтобы изменить содержимое внедренного документа Word, сначала необходимо получить доступ к встроенному приложению, а затем сам документ. Как только код получит доступ к OLEObject, ему потребуется фактический Object, с помощью которого можно обратиться к приложению и документу.

Обратите внимание, что было бы целесообразно присвоить объекту OLE имя, а не полагаться на объект, созданный в Excel. Такие имена имеют неприятную тенденцию к изменению, если добавляются дополнительные объекты или удаляются другие. Любое имя, назначенное явно, останется нетронутым. Это необходимо выполнить только один раз на рабочем листе (основываясь на полном примере кода):

ws.OLEObjects("Object 4").Name = "WordDoc" 'for example, can be any string you prefer

Тогда, если вы решите сделать это, в полном коде это будет ws.OLEObjects("WordDoc") [ 118]

В конце процедуры строка ws.Cells(1, 1).Select деактивирует внедренный объект, выбирая ячейку на листе. Если вы хотите оставить документ Word активным, чтобы пользователь мог работать с ним, просто удалите эту строку.

Sub ok()
    Dim wb As Excel.Workbook
    Dim ws As Excel.Worksheet
    Dim doc As Object 'Word.Document
    Dim wdObj As Object, wdTable As Object 'Word.Table

    Set wb = ActiveWorkbook
    Set ws = wb.Sheets("Sheet1")
    Set wdObj = ws.OLEObjects("Object 4")
    wdObj.Activate
    Set doc = wdObj.Object.Application.ActiveDocument
    Set wdTable = doc.Tables(1)
    wdTable.PreferredWidthType = 2 ' Word.WdPreferredWidthType.wdPreferredWidthPercent
    wdTable.PreferredWidth = 95
    ws.Cells(1, 1).Select
End Sub
0
ответ дан Cindy Meister 15 January 2019 в 16:19
поделиться
Другие вопросы по тегам:

Похожие вопросы: