Nota
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
En este tema se muestra cómo usar las clases del SDK de Open XML para Office para convertir mediante programación un documento de Microsoft Word que contiene código VBA (y tiene una extensión .docm) en un documento estándar (con una extensión .docx). Contiene un método de ejemplo ConvertDOCMtoDOCX
para ilustrar esta tarea.
Método ConvertDOCMtoDOCX
El ConvertDOCMtoDOCX
método de ejemplo se puede usar para convertir un documento de Word que contiene código VBA (y tiene una extensión .docm) en un documento estándar (con una extensión .docx). Use este método para quitar las macros y la parte vbaProject que los contenga de un documento almacenado en formato de archivo .docm. El método acepta un único parámetro que indica el nombre del archivo que desea convertir.
static void ConvertDOCMtoDOCX(string fileName)
Encontrará el listado completo de códigos para el método en la sección Código de ejemplo.
Llamar al método de ejemplo
Para llamar al método de ejemplo, pase una cadena que contenga el nombre del archivo que desea convertir. El código de ejemplo siguiente muestra un ejemplo.
ConvertDOCMtoDOCX(args[0]);
Partes y la parte vbaProject
Un paquete de documento de procesamiento de texto como, por ejemplo, un archivo con extensión .docx o .docm, es de hecho un archivo .zip formado por varias partes. Puede concebir cada parte como algo parecido a un archivo externo. Una parte tiene un tipo de contenido determinado y puede incluir contenido equivalente a un archivo XML externo, archivo binario, archivo de imagen, etc., en función del tipo. El estándar que define cómo se almacenan los documentos Open XML en archivos .zip se llama Open Packaging Conventions (Convenciones de empaquetado abierto). Para obtener más información sobre las convenciones de empaquetado abierto, vea ISO/IEC 29500-2:2021.
Al crear y guardar una macro VBA en un documento, Word agrega una nueva parte binaria llamada vbaProject que contiene la representación interna de su proyecto de macro. En la siguiente imagen del Explorador de documentos de la Herramienta de productividad del SDK de Open XML para Microsoft Office se muestran los elementos de documento de un documento de ejemplo que contiene una macro. La parte vbaProject esta resaltada.
Figura 1. La parte vbaProject
La tarea de convertir un documento con macros habilitadas en otro sin macros habilitadas, por lo tanto, consiste en gran medida en quitar la parte vbaProject del paquete de documentos.
Funcionamiento del código de ejemplo
El código de ejemplo modifica el documento que especifique, con lo que se comprueba que el documento contenga una parte vbaProject y se elimina la parte. Una vez que el código elimine la parte, cambia el tipo de documento internamente y le cambia el nombre de modo que usa la extensión .docx.
El código comienza abriendo el documento mediante el Open
método e indicando que el documento debe estar abierto para el acceso de lectura y escritura (el parámetro true final). A continuación, el código recupera una referencia al elemento Document mediante la MainDocumentPart
propiedad del documento de procesamiento de texto.
bool fileChanged = false;
using (WordprocessingDocument document = WordprocessingDocument.Open(fileName, true))
{
// Access the main document part.
var docPart = document.MainDocumentPart ?? throw new ArgumentNullException("MainDocumentPart is null.");
No basta con eliminar la parte del documento. También debe convertir el tipo de documento internamente. El SDK de Open XML proporciona una manera de realizar esta tarea: puede llamar al método document ChangeDocumentType
e indicar el nuevo tipo de documento (en este caso, proporcionar el WordprocessingDocumentType.Document valor enumerado).
También debe cambiar el nombre del archivo. Sin embargo, no puede hacerlo mientras el archivo esté abierto. El bloque de uso cierra el archivo al final del bloque. Por lo tanto, debe tener alguna manera de indicar al código después del bloque que ha modificado el archivo: la fileChanged
variable booleana realiza un seguimiento de esta información por usted.
// Look for the vbaProject part. If it is there, delete it.
var vbaPart = docPart.VbaProjectPart;
if (vbaPart is not null)
{
// Delete the vbaProject part.
docPart.DeletePart(vbaPart);
A continuación, el código cambia el nombre del documento recién modificado. Para ello, el código crea un nombre de archivo nuevo cambiando la extensión; comprueba que existe el archivo de salida y lo elimina, y por último, traslada el archivo del nombre de archivo anterior al nombre de archivo nuevo.
// If anything goes wrong in this file handling,
// the code will raise an exception back to the caller.
if (fileChanged)
{
// Create the new .docx filename.
var newFileName = Path.ChangeExtension(fileName, ".docx");
// If it already exists, it will be deleted!
if (File.Exists(newFileName))
{
File.Delete(newFileName);
}
// Rename the file.
File.Move(fileName, newFileName);
}
Código de ejemplo
A continuación se muestra el ejemplo de código completo ConvertDOCMtoDOCX
en C# y Visual Basic.
static void ConvertDOCMtoDOCX(string fileName)
{
bool fileChanged = false;
using (WordprocessingDocument document = WordprocessingDocument.Open(fileName, true))
{
// Access the main document part.
var docPart = document.MainDocumentPart ?? throw new ArgumentNullException("MainDocumentPart is null.");
// Look for the vbaProject part. If it is there, delete it.
var vbaPart = docPart.VbaProjectPart;
if (vbaPart is not null)
{
// Delete the vbaProject part.
docPart.DeletePart(vbaPart);
// Change the document type to
// not macro-enabled.
document.ChangeDocumentType(WordprocessingDocumentType.Document);
// Track that the document has been changed.
fileChanged = true;
}
}
// If anything goes wrong in this file handling,
// the code will raise an exception back to the caller.
if (fileChanged)
{
// Create the new .docx filename.
var newFileName = Path.ChangeExtension(fileName, ".docx");
// If it already exists, it will be deleted!
if (File.Exists(newFileName))
{
File.Delete(newFileName);
}
// Rename the file.
File.Move(fileName, newFileName);
}
}