Как проверить открыт ли word документ

Spirtuoz

0 / 0 / 0

Регистрация: 31.01.2021

Сообщений: 1

1

Проверка, открыт ли Ворд

31.01.2021, 22:25. Показов 3841. Ответов 4

Метки нет (Все метки)


Студворк — интернет-сервис помощи студентам

Добрый день! Столкнулся с таким вопросом.

Данный код открывает целевой документ Word

Visual Basic
1
2
3
4
Set wd = New Word.Application
Set wdDoc = wd.Documents.Open _
(ThisWorkbook.Path & "" & "Акт.docm")
wd.Visible = True

Однако, если данный документ уже открыт, макрос с данным кодом зависает. Как сделать, чтобы он проверял, открыт ли данный файл («Акт.docm») и:
— если открыт, то переходил к следующему действию
— если закрыт то использовался код выше и переходил к следующему действию.

Надеюсь на вашу помощь.



0



4038 / 1423 / 394

Регистрация: 07.08.2013

Сообщений: 3,541

01.02.2021, 03:34

2

можно проверить наличие файла с именем
Chr(129) & «$т.docm»
в папке где расположен ваш файл Акт.docm
если есть то файл открыт



0



811 / 465 / 181

Регистрация: 09.03.2009

Сообщений: 1,577

01.02.2021, 11:29

3

snipe, этот файл может остаться от предыдущего вылета ворда, так что не показатель открытости и блокирования.



0



NewMaNew

5 / 5 / 0

Регистрация: 02.09.2020

Сообщений: 32

01.02.2021, 12:25

4

прошу прощения, не то ответил

Добавлено через 10 минут
решение:

Visual Basic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
Function FileInWordOpen(DokName As String) As Boolean
Dim wd
wd = CreateObject("Word.Application")
Dim wDoc
wDoc = CreateObject("Word.Document")
 
Dim i As Long, s As String
On Error Resume Next
Set wd = GetObject(, "Word.Application")
On Error GoTo NO_WORD_FOUND
If wd Is Nothing Then
    FileInWordOpen = False
End If
For i = 1 To wd.Documents.Count
  s = wd.Documents(i)
  If InStr(DokName, s) <> 0 Then
     FileInWordOpen = True
     Exit Function
  End If
Next
 
NO_WORD_FOUND:
 
 FileInWordOpen = False
 
 End Function
Sub testdocopened()
Debug.Print FileInWordOpen("test.docx")
End Sub



0



Alex77755

11482 / 3773 / 677

Регистрация: 13.02.2009

Сообщений: 11,145

01.02.2021, 14:00

5

Попадалась функция проверки открыт ли файл:

Visual Basic
1
2
3
4
5
6
Function IsBookOpen(wbFullName As String) As Boolean
    On Error Resume Next
    Open wbFullName For Random Access Read Write Lock Read Write As 1
    close 1
    IsBookOpen = Err
End Function



0



Группа: Пользователи

Ранг: Прохожий

Сообщений: 7


Репутация:

0

±

Замечаний:
0% ±


Добрый день! Столкнулся с таким вопросом.

Данный код открывает целевой документ Word
[vba]

Код

Set wd = New Word.Application
Set wdDoc = wd.Documents.Open _
(ThisWorkbook.Path & «» & «Акт.docm»)
wd.Visible = True

[/vba]

Однако, если данный документ уже открыт, макрос зависает. Как сделать, чтобы он проверял, открыт ли данный файл («Акт.docm») и
— если открыт, то переходил к следующему действию
— если закрыт то использовался код выше и переходил к следующему действию.

Надеюсь на вашу помощь.

You can enumerate all Word windows and try to find one with that document. Also if you try to open this file, while it’s opened in Word, you will get IOException. But it’s not perfect solution :(
Here is solution:

using System;
using System.Collections.Generic;
using System.IO;
using System.Runtime.InteropServices;
using System.Text;

namespace WordExampleApp
{
    class Program
    {
        const int ERROR_SHARING_VIOLATION = -2147024864;
        static readonly string WORD_CLASS_NAME = "OpusApp";
        static readonly string WORD_DOCUMENT_CLASS_NAME = "_WwB";

        delegate bool EnumWindowProc(IntPtr hWnd, IntPtr parameter);

        static void Main(string[] args)
        {
            // Path to exist word document
            string filePath = @"C:tempasdasd.docx";

            string documentName = Path.GetFileNameWithoutExtension(filePath);
            var isDocOpened = IsDocumentOpened(documentName);
            Console.WriteLine("Is document opened: {0}", isDocOpened);

            bool canRead = CanReadFile(filePath);
            Console.WriteLine("Can read file: {0}", canRead);
        }
        private static bool CanReadFile(string path)
        {
            try {
                using (var fs = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.None)) { }
                return true;
            }
            catch (IOException ex) {
                if (ex.HResult == ERROR_SHARING_VIOLATION)
                    return false;
                else throw;
            }
        }

        private static bool IsDocumentOpened(string documentName)
        {
            IntPtr hwnd = FindWindow(WORD_CLASS_NAME, documentName + " - Word");
            List<IntPtr> childs = GetChildWindows(hwnd);
            var classText = new StringBuilder("", 1024);
            var windowText = new StringBuilder("", 1024);

            foreach (var childHwnd in childs)
            {
                if (0 == GetClassName(childHwnd, classText, 1024)) {
                    // something wrong
                }
                if (0 == GetWindowText(childHwnd, windowText, 1024)) {
                    // something wrong
                }
                var className = classText.ToString();
                var windowName = windowText.ToString();
                if (className == WORD_DOCUMENT_CLASS_NAME && windowName == documentName)
                    return true;

                classText.Clear();
                windowText.Clear();
            }
            return false;
        }
        public static List<IntPtr> GetChildWindows(IntPtr parent)
        {
            List<IntPtr> result = new List<IntPtr>();
            GCHandle gcHandle = GCHandle.Alloc(result);
            try {
                EnumWindowProc childProc = new EnumWindowProc(EnumWindow);
                EnumChildWindows(parent, childProc, GCHandle.ToIntPtr(gcHandle));
            }
            finally {
                if (gcHandle.IsAllocated)
                    gcHandle.Free();
            }
            return result;
        }
        private static bool EnumWindow(IntPtr handle, IntPtr pointer)
        {
            GCHandle gch = GCHandle.FromIntPtr(pointer);
            List<IntPtr> list = gch.Target as List<IntPtr>;
            if (list == null)
                throw new InvalidCastException("GCHandle Target could not be cast as List<IntPtr>");
            list.Add(handle);
            return true;
        }

        [DllImport("user32", ExactSpelling = false, CharSet = CharSet.Auto)]
        internal static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

        [DllImport("user32.dll")]
        [return: MarshalAs(UnmanagedType.Bool)]
        static extern bool EnumChildWindows(IntPtr hwndParent, EnumWindowProc lpEnumFunc, IntPtr lParam);

        [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
        static extern int GetClassName(IntPtr hWnd, StringBuilder lpClassName, int nMaxCount);

        [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
        public static extern int GetWindowText(IntPtr hWnd, StringBuilder lpWindowText, int nMaxCount);
    }
}

Sub Test()  

     Const DocFile$ = «D:123.doc»  
 Const MyDebug As Boolean = True ‘ Флаг отладки  

     ‘ Проверить  занятость файла  
 If IsOpen(DocFile) Then  
   MsgBox «Файл занят другим пользователем!», vbCritical, DocFile  
   Exit Sub  
 End If  

     Dim objWord As Object, IsNewApp As Boolean  

     ‘ Попытаться использовать ранее открытое приложение WinWord (это быстрее)  
 On Error Resume Next  
 Set objWord = GetObject(, «Word.Application»)  
 If Err Then  
   ‘ Открытое приложение WinWord не нвйдено — создать новое  
   Set objWord = CreateObject(«Word.Application»)  
   IsNewApp = True  
 End If  
 On Error GoTo exit_  

     ‘ Открыть документ DocFile  
 With objWord  
   If MyDebug Then .Visible = True  ‘<— для отладки  
   With .Documents.Open(DocFile)  
     ‘ Что-то сделать с документом  
     .Content.Font.Name = «Arial»  
     ‘ …  
     .Close True  
   End With  
   If IsNewApp Then .Quit  
 End With  

    exit_:  

     ‘ Обязательно освободить память, занимаемую объектной переменной  
 Set objWord = Nothing  

     ‘ При ошибке — сообщить  
 If Err Then MsgBox Err.Description, vbCritical, «Ошибка»  

    End Sub  

  Function IsOpen(File$) As Boolean  
 Dim FN%  
 FN = FreeFile  
 On Error Resume Next  
 Open File For Random Access Read Write Lock Read Write As #FN  
 Close #FN  
 IsOpen = Err  
End Function

246

08 декабря 2005 года

GIZMO

1.8K / / 30.07.2004

Цитата:

Originally posted by richel
Как проверить, открыт ли документ Ворд? И если открыт, как осуществить прерывание обработки текста этого документа, по сути дела, отмену?
Желательно пример для OLE-сервера.
Ищу в интернете, намеков по этому вопросу не нахожу. Неужели это простой вопрос?:o

GetActiveOleObject позволит приконнектится к Word-у, у объекта Application есть св-во Documents, у того есть св-во Items и т.д.

Код:

Variant Word, Document;

    Word = GetActiveOleObject(«Word.Application»);

       
    Document = Word.Exec(PropertyGet(«Documents»)).Exec(Function(«Item») << «Документ1»);
    Document.Exec(Function(«Close») << wdDoNotSaveChanges);

на второй строке или матюгнется или вернет NULL, проверишь сама…
wdDoNotSaveChanges — чему равно найдешь в хедере для TWordApplication он у меня не установлен.

Sub макрос()

        Dim doc As Document

            ‘ Включение перехватчика run-ошибок, чтобы макрос продолжил работу при возникновении
        ‘ run-ошибки.
    On Error Resume Next
        ‘ Присваиваем файлу имя «doc». Если файл не открыт, то в переменной «doc» будет Nothing.
        Set doc = Documents(«C:UsersUserDesktopДокумент Microsoft Word.docx»)
    ‘ Отключение перехватчика ошибок, чтобы видеть непредвиденные ошибки.
    On Error GoTo 0

        ‘ Проверка, открыт файл или нет.
    If doc Is Nothing Then
        MsgBox «Файл не открыт.», vbInformation
    Else
        MsgBox «Файл открыт.», vbInformation
    End If

End Sub

[свернуть]

Вы можете перечислить все окна Word и попытаться найти их с этим документом. Также, если вы попытаетесь открыть этот файл, пока он откроется в Word, вы получите IOException. Но это не идеальное решение :( Вот решение:

using System;
using System.Collections.Generic;
using System.IO;
using System.Runtime.InteropServices;
using System.Text;

namespace WordExampleApp
{
    class Program
    {
        const int ERROR_SHARING_VIOLATION = -2147024864;
        static readonly string WORD_CLASS_NAME = "OpusApp";
        static readonly string WORD_DOCUMENT_CLASS_NAME = "_WwB";

        delegate bool EnumWindowProc(IntPtr hWnd, IntPtr parameter);

        static void Main(string[] args)
        {
            // Path to exist word document
            string filePath = @"C:tempasdasd.docx";

            string documentName = Path.GetFileNameWithoutExtension(filePath);
            var isDocOpened = IsDocumentOpened(documentName);
            Console.WriteLine("Is document opened: {0}", isDocOpened);

            bool canRead = CanReadFile(filePath);
            Console.WriteLine("Can read file: {0}", canRead);
        }
        private static bool CanReadFile(string path)
        {
            try {
                using (var fs = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.None)) { }
                return true;
            }
            catch (IOException ex) {
                if (ex.HResult == ERROR_SHARING_VIOLATION)
                    return false;
                else throw;
            }
        }

        private static bool IsDocumentOpened(string documentName)
        {
            IntPtr hwnd = FindWindow(WORD_CLASS_NAME, documentName + " - Word");
            List<IntPtr> childs = GetChildWindows(hwnd);
            var classText = new StringBuilder("", 1024);
            var windowText = new StringBuilder("", 1024);

            foreach (var childHwnd in childs)
            {
                if (0 == GetClassName(childHwnd, classText, 1024)) {
                    // something wrong
                }
                if (0 == GetWindowText(childHwnd, windowText, 1024)) {
                    // something wrong
                }
                var className = classText.ToString();
                var windowName = windowText.ToString();
                if (className == WORD_DOCUMENT_CLASS_NAME && windowName == documentName)
                    return true;

                classText.Clear();
                windowText.Clear();
            }
            return false;
        }
        public static List<IntPtr> GetChildWindows(IntPtr parent)
        {
            List<IntPtr> result = new List<IntPtr>();
            GCHandle gcHandle = GCHandle.Alloc(result);
            try {
                EnumWindowProc childProc = new EnumWindowProc(EnumWindow);
                EnumChildWindows(parent, childProc, GCHandle.ToIntPtr(gcHandle));
            }
            finally {
                if (gcHandle.IsAllocated)
                    gcHandle.Free();
            }
            return result;
        }
        private static bool EnumWindow(IntPtr handle, IntPtr pointer)
        {
            GCHandle gch = GCHandle.FromIntPtr(pointer);
            List<IntPtr> list = gch.Target as List<IntPtr>;
            if (list == null)
                throw new InvalidCastException("GCHandle Target could not be cast as List<IntPtr>");
            list.Add(handle);
            return true;
        }

        [DllImport("user32", ExactSpelling = false, CharSet = CharSet.Auto)]
        internal static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

        [DllImport("user32.dll")]
        [return: MarshalAs(UnmanagedType.Bool)]
        static extern bool EnumChildWindows(IntPtr hwndParent, EnumWindowProc lpEnumFunc, IntPtr lParam);

        [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
        static extern int GetClassName(IntPtr hWnd, StringBuilder lpClassName, int nMaxCount);

        [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
        public static extern int GetWindowText(IntPtr hWnd, StringBuilder lpWindowText, int nMaxCount);
    }
}

Понравилась статья? Поделить с друзьями:
  • Как проверить совпадение текста в excel
  • Как проверить остаток от деления в excel
  • Как проверить наличие значения в массиве excel
  • Как проверить совпадение в ячейках excel
  • Как проверить орфографию в word выделенного текста