На счёт того, как определить режим открытия файла (Read Only/Read-Write), я помню, что это как-то не сложно, но что-то не нашёл пока в своей копилке. А вот использование WinAPI для получения сетевого имени компа - это уже явный перебор. Проще всего его можно получить из переменных окружения, чтение которых производит функция Environ [vba]
Код
Function ThisComputerName$(): ThisComputerName$ = Split(Environ(6), "=")(1): End Function
[/vba]Под спойлером примеры чтения переменных среды и ещё несколько простых способов получения имени компьютера
[vba]
Код
Private Sub OS_Environment_Variable_Info() ' информация о переменных среды ОС Dim i% 'On Error Resume Next For i = 1 To 63 If Len(Environ(i)) > 0 Then Debug.Print i, Environ(i) Next i End Sub
Private Sub OS_UserName() Dim objWMIService Set objWMIService = GetObject("WinMgmts:{impersonationLevel=impersonate}!\\" & "." & "\root\cimv2") Dim colOperatingSystems, objOperatingSystem Set colOperatingSystems = objWMIService.ExecQuery("Select * from Win32_OperatingSystem") For Each objOperatingSystem In colOperatingSystems Debug.Print "OS RegisteredUser: " & objOperatingSystem.RegisteredUser Next End Sub
Private Sub OS_UserName_() Dim xOS With GetObject("WinMgmts:{impersonationLevel=impersonate}!\\" & "." & "\root\cimv2") For Each xOS In .ExecQuery("Select * from Win32_OperatingSystem") Debug.Print "OS RegisteredUser: " & xOS.RegisteredUser Next End With End Sub
Private Sub REG_UserName() Dim oReg, sKeyPath$, sValueName$, sValue$ Set oReg = GetObject("WinMgmts:{ImpersonationLevel=Impersonate}!\\.\root\default:StdRegProv") sKeyPath = "Software\Microsoft\Windows\CurrentVersion\Explorer" sValueName = "Logon User Name" oReg.GetExpandedStringValue &H80000001, sKeyPath, sValueName, sValue Debug.Print sValue End Sub Private Sub Net_UserName() Debug.Print CreateObject("Wscript.Network").UserName Debug.Print Application.UserName End Sub
[/vba]
На счёт того, как определить режим открытия файла (Read Only/Read-Write), я помню, что это как-то не сложно, но что-то не нашёл пока в своей копилке. А вот использование WinAPI для получения сетевого имени компа - это уже явный перебор. Проще всего его можно получить из переменных окружения, чтение которых производит функция Environ [vba]
Код
Function ThisComputerName$(): ThisComputerName$ = Split(Environ(6), "=")(1): End Function
[/vba]Под спойлером примеры чтения переменных среды и ещё несколько простых способов получения имени компьютера
[vba]
Код
Private Sub OS_Environment_Variable_Info() ' информация о переменных среды ОС Dim i% 'On Error Resume Next For i = 1 To 63 If Len(Environ(i)) > 0 Then Debug.Print i, Environ(i) Next i End Sub
Private Sub OS_UserName() Dim objWMIService Set objWMIService = GetObject("WinMgmts:{impersonationLevel=impersonate}!\\" & "." & "\root\cimv2") Dim colOperatingSystems, objOperatingSystem Set colOperatingSystems = objWMIService.ExecQuery("Select * from Win32_OperatingSystem") For Each objOperatingSystem In colOperatingSystems Debug.Print "OS RegisteredUser: " & objOperatingSystem.RegisteredUser Next End Sub
Private Sub OS_UserName_() Dim xOS With GetObject("WinMgmts:{impersonationLevel=impersonate}!\\" & "." & "\root\cimv2") For Each xOS In .ExecQuery("Select * from Win32_OperatingSystem") Debug.Print "OS RegisteredUser: " & xOS.RegisteredUser Next End With End Sub
Private Sub REG_UserName() Dim oReg, sKeyPath$, sValueName$, sValue$ Set oReg = GetObject("WinMgmts:{ImpersonationLevel=Impersonate}!\\.\root\default:StdRegProv") sKeyPath = "Software\Microsoft\Windows\CurrentVersion\Explorer" sValueName = "Logon User Name" oReg.GetExpandedStringValue &H80000001, sKeyPath, sValueName, sValue Debug.Print sValue End Sub Private Sub Net_UserName() Debug.Print CreateObject("Wscript.Network").UserName Debug.Print Application.UserName End Sub
If GetAttr(ThisWorkbook.FullName) And 1 Then Exit Sub
[/vba]
что то не работает, при открытии в чтении всё равно обращается к Excel.ActiveWorkbook.Save.
Может я как то криво вопрос задал, есть файл.xls который лежит в локальной сети, при открытии кем либо этого файла в режиме записи Например USER1, срабатывает автоматический запуск: [vba]
Код
Private Declare Function GetComputerName Lib "kernel32" Alias "GetComputerNameA" (ByVal lpBuffer As String, nSize As Long) As Long
Sub test() Dim scomp As String scomp = Space(255) h = GetComputerName(scomp, 255) Range("C2").Value = Trim(scomp) Excel.ActiveWorkbook.Save End Sub
[/vba] То-есть записывает имя пользователя компьютера в ячейку ("C2") и сохраняет файл.
Надо что бы при открытии другим пользователем, уже в режиме чтения, например USER2 не происходило автоматическое срабатывание: [vba]
Код
Private Declare Function GetComputerName Lib "kernel32" Alias "GetComputerNameA" (ByVal lpBuffer As String, nSize As Long) As Long
Sub test() Dim scomp As String scomp = Space(255) h = GetComputerName(scomp, 255) Range("C2").Value = Trim(scomp) Excel.ActiveWorkbook.Save End Sub
[/vba]
Смысл всего этого таков, видеть в ячейке имя компьютера у кого файл в режиме редактирования/записи.
If GetAttr(ThisWorkbook.FullName) And 1 Then Exit Sub
[/vba]
что то не работает, при открытии в чтении всё равно обращается к Excel.ActiveWorkbook.Save.
Может я как то криво вопрос задал, есть файл.xls который лежит в локальной сети, при открытии кем либо этого файла в режиме записи Например USER1, срабатывает автоматический запуск: [vba]
Код
Private Declare Function GetComputerName Lib "kernel32" Alias "GetComputerNameA" (ByVal lpBuffer As String, nSize As Long) As Long
Sub test() Dim scomp As String scomp = Space(255) h = GetComputerName(scomp, 255) Range("C2").Value = Trim(scomp) Excel.ActiveWorkbook.Save End Sub
[/vba] То-есть записывает имя пользователя компьютера в ячейку ("C2") и сохраняет файл.
Надо что бы при открытии другим пользователем, уже в режиме чтения, например USER2 не происходило автоматическое срабатывание: [vba]
Код
Private Declare Function GetComputerName Lib "kernel32" Alias "GetComputerNameA" (ByVal lpBuffer As String, nSize As Long) As Long
Sub test() Dim scomp As String scomp = Space(255) h = GetComputerName(scomp, 255) Range("C2").Value = Trim(scomp) Excel.ActiveWorkbook.Save End Sub
[/vba]
Смысл всего этого таков, видеть в ячейке имя компьютера у кого файл в режиме редактирования/записи.managerauto
Сообщение отредактировал managerauto - Суббота, 10.12.2016, 18:03
Private Declare Function GetComputerName Lib "kernel32" Alias "GetComputerNameA" (ByVal lpBuffer As String, nSize As Long) As Long
Private Sub Workbook_Open() If ActiveWorkbook.ReadOnly Then Exit Sub Dim scomp As String scomp = Space(255) h = GetComputerName(scomp, 255) Range("C2").Value = Trim(scomp) Excel.ActiveWorkbook.Save End Sub
[/vba]
User1 открывает книгу в режиме записи, в ячейку (например ("C2") записывается имя компьютера и сохраняется, User2 открывает в режиме чтения, видит имя компьютера у кого открыт файл в режиме записи. Может кому нибудь пригодится.
Вопрос решен: [vba]
Код
Private Declare Function GetComputerName Lib "kernel32" Alias "GetComputerNameA" (ByVal lpBuffer As String, nSize As Long) As Long
Private Sub Workbook_Open() If ActiveWorkbook.ReadOnly Then Exit Sub Dim scomp As String scomp = Space(255) h = GetComputerName(scomp, 255) Range("C2").Value = Trim(scomp) Excel.ActiveWorkbook.Save End Sub
[/vba]
User1 открывает книгу в режиме записи, в ячейку (например ("C2") записывается имя компьютера и сохраняется, User2 открывает в режиме чтения, видит имя компьютера у кого открыт файл в режиме записи. Может кому нибудь пригодится.managerauto
Сообщение отредактировал managerauto - Четверг, 15.12.2016, 16:42
Это всё, конечно, здорово, но только при одном листе в книге. Потому что только в таком случае один и тот же лист всегда будет при открытии ActiveSheet, на который без указания имени листа можно записать данные из процедуры Workbook_Open, размещённой в модуле ЭтаКнига Ну и, конечно, если Вы предпочитаете использовать WinAPI для того, чтобы узнать имя компьютера, то никто запретить это не может. Каждый извращается так, как он хочет
Это всё, конечно, здорово, но только при одном листе в книге. Потому что только в таком случае один и тот же лист всегда будет при открытии ActiveSheet, на который без указания имени листа можно записать данные из процедуры Workbook_Open, размещённой в модуле ЭтаКнига Ну и, конечно, если Вы предпочитаете использовать WinAPI для того, чтобы узнать имя компьютера, то никто запретить это не может. Каждый извращается так, как он хочетAlex_ST
проблема в другом: 1. Гарантировано в книге есть только первый лист, следовательно метки надо писать на первом листе. 2. User1 может смутить некая информация на его "любимом" первом листе и он может удалить метку, а потом сохранить. 3. Кроме того, User1 может удалить лист с меткой целиком и после этого записать файл в таком случае User2 не узнает кто открыл файлик
т.е. деяние благое, на радость юзьверя, а он может быть как "суровый челябинский мужЫк", эму это нафиг не надо. Короче: нет "защиты от дурака"
...и кстати разве файловый сервер/домен не могут проинформировать о том кто открыл файл, причем любой, а не только ехелевский???
проблема в другом: 1. Гарантировано в книге есть только первый лист, следовательно метки надо писать на первом листе. 2. User1 может смутить некая информация на его "любимом" первом листе и он может удалить метку, а потом сохранить. 3. Кроме того, User1 может удалить лист с меткой целиком и после этого записать файл в таком случае User2 не узнает кто открыл файлик
т.е. деяние благое, на радость юзьверя, а он может быть как "суровый челябинский мужЫк", эму это нафиг не надо. Короче: нет "защиты от дурака"
...и кстати разве файловый сервер/домен не могут проинформировать о том кто открыл файл, причем любой, а не только ехелевский???dim34rus
Извращение - это писать формулы в Word'овских таблицах. ЯД 410014340958327
Сообщение отредактировал dim34rus - Пятница, 16.12.2016, 14:34
разве файловый сервер/домен не могут проинформировать о том кто открыл файл
К сожалению, хоть это и возможно в принципе, но доступно далеко не любому пользователю файла, расшаренного на серваке. Для этого нужно чтобы сисадмины, имеющие соответствующие права доступа, хоть чуть-чуть напрягли извилины с целью облегчить жизнь юзвергам и написали общедоступный скриптик, который получив имя файла, ответит, какой из компов его держит открытым. Но наши замечания и конструктивные предложения топик-стартеру, похоже, не интересны. Поэтому он выложил "труды своих плодов" в таком виде, в каком считает нужным и который его удовлетворяет. У нас свобода мнений. И если ему так удобно, то никто не может запретить юзать сырую процедуру.
разве файловый сервер/домен не могут проинформировать о том кто открыл файл
К сожалению, хоть это и возможно в принципе, но доступно далеко не любому пользователю файла, расшаренного на серваке. Для этого нужно чтобы сисадмины, имеющие соответствующие права доступа, хоть чуть-чуть напрягли извилины с целью облегчить жизнь юзвергам и написали общедоступный скриптик, который получив имя файла, ответит, какой из компов его держит открытым. Но наши замечания и конструктивные предложения топик-стартеру, похоже, не интересны. Поэтому он выложил "труды своих плодов" в таком виде, в каком считает нужным и который его удовлетворяет. У нас свобода мнений. И если ему так удобно, то никто не может запретить юзать сырую процедуру.Alex_ST
Каждый человек, обратившийся на данный ресурс для помощи в решении его задачи, само собой не на столько силён в решении таких вопрос(ибо смысл обращаться) и каждый пытается донести её так как он сам это видит, если рассматривать решение задачи со стороны подготовленных людей, понятно дело видно, что можно это было сделать 10 разными способами(в зависимости от преследуемых целей) и посмотреть на перспективы работы в дальнейшем. А по мне, то что мне надо было, вроде работает, будем в дальнейшем решать проблемы по мере их поступления
в каком считает нужным и который его удовлетворяет.
тут вы правы
Каждый человек, обратившийся на данный ресурс для помощи в решении его задачи, само собой не на столько силён в решении таких вопрос(ибо смысл обращаться) и каждый пытается донести её так как он сам это видит, если рассматривать решение задачи со стороны подготовленных людей, понятно дело видно, что можно это было сделать 10 разными способами(в зависимости от преследуемых целей) и посмотреть на перспективы работы в дальнейшем. А по мне, то что мне надо было, вроде работает, будем в дальнейшем решать проблемы по мере их поступления
managerauto, спасибо, что не сильно обиделись и сдержали эмоции. Просто странно видеть человека, которому вместо примерённого им сложного решения предлагают простой аналог из одной команды, а он продолжает настаивать на своём. К тому же Ваше решение мало того, что длиннее, но ещё и использует мощнейший аппарат WinAPI, который, к сожалению, практически не запоминаем и потому с ним можно работать только со справочником. Да и способ хранения имени пользователя в ячейке единственного листа, согласитесь, чреват последствиями в процессе эксплуатации. О чём Вам говорил не только я. Мест для хранения в файле масса. И ячейка открытого листа - одно из не самых удобных. Самое простое решение - задайте Public-переменную. При открытии файла проверяйте её на пустоту (""). Если она ="", то пользователь первый открыл и процедура запишет в неё имя пользователя. Второй открывший может получить MsgBox с этим именем. А при закрытии файла переменные сбрасываются автоматически. Если так не пройдёт (я не могу сам проверить работу с разных компов в режиме общего доступа), то записывайте имя пользователя в какую-нибудь из коллекций книги (например, в Names или в Properties) но тогда имя при закрытии книги нужно удалять. Если же всё-таки хранить на листе, то на шибко спрятанном (VeryHidden). Такой лист нельзя будет отобразить никак кроме как из VBE и никто о нем просто не будет знать. Но программно обращаться к нему так же просто как и к обычному листу.
managerauto, спасибо, что не сильно обиделись и сдержали эмоции. Просто странно видеть человека, которому вместо примерённого им сложного решения предлагают простой аналог из одной команды, а он продолжает настаивать на своём. К тому же Ваше решение мало того, что длиннее, но ещё и использует мощнейший аппарат WinAPI, который, к сожалению, практически не запоминаем и потому с ним можно работать только со справочником. Да и способ хранения имени пользователя в ячейке единственного листа, согласитесь, чреват последствиями в процессе эксплуатации. О чём Вам говорил не только я. Мест для хранения в файле масса. И ячейка открытого листа - одно из не самых удобных. Самое простое решение - задайте Public-переменную. При открытии файла проверяйте её на пустоту (""). Если она ="", то пользователь первый открыл и процедура запишет в неё имя пользователя. Второй открывший может получить MsgBox с этим именем. А при закрытии файла переменные сбрасываются автоматически. Если так не пройдёт (я не могу сам проверить работу с разных компов в режиме общего доступа), то записывайте имя пользователя в какую-нибудь из коллекций книги (например, в Names или в Properties) но тогда имя при закрытии книги нужно удалять. Если же всё-таки хранить на листе, то на шибко спрятанном (VeryHidden). Такой лист нельзя будет отобразить никак кроме как из VBE и никто о нем просто не будет знать. Но программно обращаться к нему так же просто как и к обычному листу.Alex_ST
С уважением, Алексей MS Excel 2003 - the best!!!
Сообщение отредактировал Alex_ST - Пятница, 16.12.2016, 21:39
Просто странно видеть человека, которому вместо примерённого им сложного решения предлагают простой аналог из одной команды, а он продолжает настаивать на своём.
Самое простое решение - задайте Public-переменную. При открытии файла проверяйте её на пустоту (""). Если она ="", то пользователь первый открыл и процедура запишет в неё имя пользователя.
Мне кажется способов много, в зависимости от преследуемых целей
Просто странно видеть человека, которому вместо примерённого им сложного решения предлагают простой аналог из одной команды, а он продолжает настаивать на своём.
Самое простое решение - задайте Public-переменную. При открытии файла проверяйте её на пустоту (""). Если она ="", то пользователь первый открыл и процедура запишет в неё имя пользователя.
Мне кажется способов много, в зависимости от преследуемых целей managerauto
использование WinAPI для получения сетевого имени компа - это уже явный перебор.
Часто сталкиваюсь с подобными суждениями, и всегда удивляюсь, ведь функции WinAPI не "священная корова" и даже не "Святой Грааль", это просто один из универсальных инструментов встроенных в само ядро системы. Тут, думаю, на усмотрение писателя, - какими метафорами пользоваться? Конечно теми какими уверенно владеешь. А такое "настороженное" отношение к ним вызвано просто незнанием предмета. Не помешало-бы тут на форуме замутить статью о том как можно использовать функции WinAPI в приложениях VBA, c хорошими примерами. Возможно кто-нибудь из писателей сподвигнется на это.
использование WinAPI для получения сетевого имени компа - это уже явный перебор.
Часто сталкиваюсь с подобными суждениями, и всегда удивляюсь, ведь функции WinAPI не "священная корова" и даже не "Святой Грааль", это просто один из универсальных инструментов встроенных в само ядро системы. Тут, думаю, на усмотрение писателя, - какими метафорами пользоваться? Конечно теми какими уверенно владеешь. А такое "настороженное" отношение к ним вызвано просто незнанием предмета. Не помешало-бы тут на форуме замутить статью о том как можно использовать функции WinAPI в приложениях VBA, c хорошими примерами. Возможно кто-нибудь из писателей сподвигнется на это.al-Ex
Сообщение отредактировал al-Ex - Суббота, 17.12.2016, 12:11
мощнейший аппарат WinAPI … к сожалению, практически не запоминаем и потому с ним можно работать только со справочником.
или Вы серьёзно думаете, что хоть кто-нибудь помнит хотя бы 25% ПЕРЕЧНЯ из этого Краткого справочника по функциям WinAPI, не говоря уж об передаваемых аргументах и возвращаемых значениях? Конечно, есть общие правила обращения к этим функциям из VB. Но сначала нужно узнать, что функция, выполняющая нужное Вам действие, есть в WinAPI, потом слазить в справочник по её использованию и уж после этого, объявив функцию в декларациях модуля (а это, согласитесь, лишние "мышкодвижения" при переносе процедур в другие проекты), можно использовать функцию в своей процедуре. Поэтому функции WinAPI и редко используются, что к ним обращаются только в случаях, когда решение с функциями VB оказывается намного сложнее. [offtop]Я, к стати, именно исходя из критерия лёгкости переноса в другие проекты, стараюсь ограничивать свои макросы одной процедурой, максимум - с вызовом подпрограмм. И всеми силами стараюсь не использовать переменные в декларациях модуля (особенно - Public) Примером тому служит моя Функция LstBox - аналог MsgBox но с выбором как в ListBox, просто скопировав текст которой в стандартный модуль любого своего проекта, можно получить достаточно удобный инструмент для ввода данных[/offtop]
мощнейший аппарат WinAPI … к сожалению, практически не запоминаем и потому с ним можно работать только со справочником.
или Вы серьёзно думаете, что хоть кто-нибудь помнит хотя бы 25% ПЕРЕЧНЯ из этого Краткого справочника по функциям WinAPI, не говоря уж об передаваемых аргументах и возвращаемых значениях? Конечно, есть общие правила обращения к этим функциям из VB. Но сначала нужно узнать, что функция, выполняющая нужное Вам действие, есть в WinAPI, потом слазить в справочник по её использованию и уж после этого, объявив функцию в декларациях модуля (а это, согласитесь, лишние "мышкодвижения" при переносе процедур в другие проекты), можно использовать функцию в своей процедуре. Поэтому функции WinAPI и редко используются, что к ним обращаются только в случаях, когда решение с функциями VB оказывается намного сложнее. [offtop]Я, к стати, именно исходя из критерия лёгкости переноса в другие проекты, стараюсь ограничивать свои макросы одной процедурой, максимум - с вызовом подпрограмм. И всеми силами стараюсь не использовать переменные в декларациях модуля (особенно - Public) Примером тому служит моя Функция LstBox - аналог MsgBox но с выбором как в ListBox, просто скопировав текст которой в стандартный модуль любого своего проекта, можно получить достаточно удобный инструмент для ввода данных[/offtop]Alex_ST
С уважением, Алексей MS Excel 2003 - the best!!!
Сообщение отредактировал Alex_ST - Суббота, 17.12.2016, 13:02