powered by simpleCommunicator - 2.0.51     © 2025 Programmizd 02
Форумы / Microsoft Access [игнор отключен] [закрыт для гостей] / интересные факты / наблюдения / анализ чужих и собственных решений
25 сообщений из 280, страница 7 из 12
интересные факты / наблюдения / анализ чужих и собственных решений
    #37726699
studieren
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Чтобы открыть отчёт в режиме предварительного просмотра и при этом сразу же задать масштаб обычно поступают так:
Код: vbnet
1.
2.
DoCmd.OpenReport "Название отчёта", acPreview
DoCmd.RunCommand acCmdZoom100


Здесь вместо "acCmdZoom100" можно также использовать другие стандартные масштабы (например acCmdZoom75 или acCmdZoom150).
А как же задать нестандартный масштаб? Ну например 125%?
Как то случайно мне попался файл, где использовался скрытое (недокументированное) свойство отчёта "ZoomControl", с помощью которого можно задать любой нестандартный масштаб.
Код: vbnet
1.
2.
DoCmd.OpenReport "Название отчёта", acPreview
Reports("Название отчёта").ZoomControl = 125


Но только есть 1 недостаток: внутри модуля отчёта этот код нельзя использовать (т.е. невозможно повесить на open или activate), только и только нужно "со стороны" сразу после OpenReport. :)
...
Рейтинг: 0 / 0
интересные факты / наблюдения / анализ чужих и собственных решений
    #37741666
studieren
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Иногда бывает полезным программно "поймать событие" нажатия команды штатного меню. Например, перед сжатием базы целесообразно удалить ненужные таблицы (скажем "Ошибки вставки", "Admin - 00" и т.д.) и "временные" запросы ("Запрос1", "Запрос2" и т.п.).
Как же сделать это?

Вот здесь я написал случай преобразования MDB файла на MDE. Теперь попробую "поймать сжатие" базы.
В первую очередь конечно же не забываем включить библиотеку "Microsoft Office XX Object Library". (вместо XX нужная версия офиса).
Итак, если у нас есть скрытая форма, открывающаяся в момент старта базы, то в модуль формы пишем так:
Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
Private WithEvents CompactDB As Office.CommandBarButton

Private Sub Form_Load()
    Set CompactDB = CommandBars.FindControl(Id:=2071)
End Sub

Private Sub CompactDB_Click(ByVal Ctrl As Office.CommandBarButton, CancelDefault As Boolean)
    On Error Resume Next
    ' Вот здесь уже пишем свой код, который выполнится раньше _
      чем штатное действия Access'а.
    ' Если нам нужно блокировать штатное действия Access, то пишем так:
    CancelDefault = True
End Sub


Если же у нас нет такой формы, то этот же код можно повесить в модуль "класс", которого следует "запускать" в момент старта базы (ну скажем в макросе "AUTOEXEC" запускаем некую VBA функция, которая и будет запускать класс). Правда в этом случае вместо "Form_Load()" следует написать "НазваниеКласса_Initialize()". :)

Итак, по этой же схеме можно поймать все штатные команды меню Access'а. Осталось выяснить Id код для каждой команды. Для "Создать MDE-файл..." Id = 2073, для "Сжать и восстановить базу данных" Id = 2071. А для других команд какой Id?
Для этого запускаем вот такой код и узнаем Id:
Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
Sub GetCommandBarControlID()
    Dim Ctrls   As CommandBarControls
    Dim Ctrl    As CommandBarControl
    Dim strCmnd As String
    
    strCmnd = InputBox("Введите фрагмент названия команды меню.", "Фрагмент")
    If Len(strCmnd) = 0 Then
        Exit Sub
    Else
        strCmnd = "*" & strCmnd & "*"
    End If
    
    Set Ctrls = CommandBars.FindControls(Type:=msoControlButton)
    For Each Ctrl In Ctrls
        If Ctrl.Caption Like strCmnd Then
            MsgBox Ctrl.Caption & "     Id = " & Ctrl.Id
        End If
    Next Ctrl
End Sub


Правда есть маленький нюанс: если в названии команды есть горячая клавиша (нижнее подчеркивание буквы), то перед этой буквы не забываем вставить & когда InputBox будет спрашивать фрагмент названия команды.
...
Рейтинг: 0 / 0
интересные факты / наблюдения / анализ чужих и собственных решений
    #37742233
ALEXIS_22
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Покопался в своих архивах. нашел вот такую табличку по кодам меню. (см. прил. файл)
...
Рейтинг: 0 / 0
интересные факты / наблюдения / анализ чужих и собственных решений
    #37744487
studieren
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ALEXIS_22,

Thank you very much!
...
Рейтинг: 0 / 0
интересные факты / наблюдения / анализ чужих и собственных решений
    #37746128
studieren
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Чуть выше (а именно вот здесь 12324615 ) я написал, что свойство "ZoomControl" нельзя использовать внутри модуля отчёта. Ну нельзя так нельзя! Но если очень хочется, то можно. :) Правда не без танцев с бубнами. :)
Чисто из-за "спортивного интереса" решил всё-таки попробовать заставить работать "ZoomControl".
Если повесить код "Me.ZoomControl = 125" на событие "Report_Activate", то происходит следующее:
Когда мы отчёт открываем первый раз, то Access ругается. Но зато потом, когда отчёт теряет фокус и обратно получает фокус, то уже не ругается. Стало быть перед "Me.ZoomControl = 125" следует добавить "On Error Resume Next". Однако, мы не получим моментального результата - масштаба 125% при первом же открытии отчёта. Как же всё таки получить моментального такого эффекта?
Итак, в модуль базы (не в модуль отчёта, а в отдельный модуль) добавляем вот такой код:
Код: vbnet
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.
30.
31.
32.
33.
34.
35.
36.
37.
Public Declare Function SetTimer Lib "user32" ( _
          ByVal Hwnd As Long, _
          ByVal nIDEvent As Long, _
          ByVal uElapse As Long, _
          ByVal lpTimerFunc As Long) As Long
Public Declare Function KillTimer Lib "user32" ( _
          ByVal Hwnd As Long, _
          ByVal nIDEvent As Long) As Long


Sub StartTimer(RunProgram As String, MSec As Long)
    If Len(RunProgram) = 0 Or MSec <= 0 Then
        Exit Sub
    Else
        strProgram = RunProgram
    End If
    SetTimer Application.hWndAccessApp, 1, MSec, AddressOf TimerProc
End Sub

Private Sub TimerProc()
    KillTimer Application.hWndAccessApp, 1
    Eval strProgram
End Sub

Function ReportZoomControl(ReportName As String, Zoom As Integer) As Boolean
    On Error Resume Next
    ' По умолчанию масштаб 125.
    If Zoom = 0 Then Zoom = 125
    
    If Len(ReportName) = 0 Then
        ReportName = Screen.ActiveReport.Name
        If Len(ReportName) = 0 Then Exit Function
    End If
    
    Reports(ReportName).ZoomControl = Zoom
    ReportZoomControl = (Err.Number = 0)
End Function



Далее, в модуле отчёта пишем так:
Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
Private Sub Report_Activate()
    Static Opened As Boolean
    DoCmd.Maximize
    If Opened = False Then
        Opened = True
        StartTimer "ReportZoomControl('" & Me.Name & "', 125)", 100
    Else
        Me.ZoomControl = 125
    End If
End Sub


Для получения "почти" моментального эффекта я взял 0,1 секунд (красным отметил 100). Если у Вас "тяжёлый" отчёт, то возможно придётся "чуть-чуть" добавить.

P.S. В принципе если требуется запуск какой-либо процедуры, но при этом не дожидаясь завершить первоначальную процедуру, а потом спустя некоторое время продолжить работу второй процедуры, то можно использовать такую схему работы.
...
Рейтинг: 0 / 0
интересные факты / наблюдения / анализ чужих и собственных решений
    #37749848
studieren
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Как-то недавно пробегал топик, где шла речь о спец. форматах. Там ещё и база была приложена с примером. Если в текстовое поле (именно только текстовое!) указать формат ">[синий]" (или blue в английских версиях), то в режиме таблицы данное поле будет окрашено синим цветом (в хелпе есть перечень цветов: Black, Blue, Green, Cyan, Red, Magenta, Yellow, White).
Что интересно если написать без ">", то такого эффекта не будет. Правда если указать цвет вместе с ">", то будет побочный эффект: все буквы будут прописными. Соответственно можно заменить на "<", но тогда буквы строчные.
А чтобы таких "побочных" эффектов не было, то нужно указать либо "!", либо "@" вместо ">", либо даже так "><" (последний вариант ещё хоть как-то логичный :) ).
Почему так, почему именно эти символы я так и не понял. Может кто-нибудь знает причину?
Есть ли ещё "загадочные" форматы? Не условные форматы (с ними вроде нет "загадочности") и не "красный цвет для отрицательных чисел", а какой-нибудь не очевидный формат? :)

Странно, но ещё можно написать и так: !@[Синий][Красный]
Тогда получим красный цвет, т.е. цвет, указанный последним в "списке".
...
Рейтинг: 0 / 0
интересные факты / наблюдения / анализ чужих и собственных решений
    #37749911
alvk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
studieren,

Лови
...
Рейтинг: 0 / 0
интересные факты / наблюдения / анализ чужих и собственных решений
    #37750540
ALEXIS_22
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alvk

Да это интересно. Только для числовых полей и полей с датами не получилось. Там другое выражение для задания формата?
...
Рейтинг: 0 / 0
интересные факты / наблюдения / анализ чужих и собственных решений
    #37750559
alvk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ALEXIS_22,

о чём речь? если поковыряться, то можно всё сделать; можно и на форуме кстати поискать, как раз с числами что-то видел
...
Рейтинг: 0 / 0
интересные факты / наблюдения / анализ чужих и собственных решений
    #37750571
studieren
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ALEXIS_22,

Я сам тоже не знаю. Вот поэтому и спросил. :)
...
Рейтинг: 0 / 0
интересные факты / наблюдения / анализ чужих и собственных решений
    #37750680
ALEXIS_22
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
studieren

Просто раскрасить поля в запросе это одно. Но практическая ценность будет намного выше если как-то задавать формат в зависимости от значения в поле. Пока не выходит. Через iif пробую.
...
Рейтинг: 0 / 0
интересные факты / наблюдения / анализ чужих и собственных решений
    #37750816
alvk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ALEXIS_22,

конкретно задачу кто-нибудь поставит?
...
Рейтинг: 0 / 0
интересные факты / наблюдения / анализ чужих и собственных решений
    #37750936
ALEXIS_22
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alvkALEXIS_22,
конкретно задачу кто-нибудь поставит?

Я вот что вспомнил. Вот так можно форматировать поля с разными типами данных:

Код: vbnet
1.
!\ [Красный] 

- текстовый,
Код: vbnet
1.
# ##0,00[Черный];(-# ##0,00)[Красный]

- числовой,
Код: vbnet
1.
dd.mm.yyyy[Синий] 

- дата \ время

Дело в том, как задать формат поля в зависимости от содержащегося в нем значения? Для числового поля черные-положительные, красные отрицательные. Это понятно. А вот допустим для текста вывести в одном поле в таблице или в запросе "Красный" - красным цветом, "Зеленый" - зеленым. Вот это как, я не знаю. И думаю возможно ли такое вообще
Иначе зачем майкрософту Format Condition например?
...
Рейтинг: 0 / 0
интересные факты / наблюдения / анализ чужих и собственных решений
    #37751271
studieren
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ALEXIS_22Дело в том, как задать формат поля в зависимости от содержащегося в нем значения? Для числового поля черные-положительные, красные отрицательные. Это понятно. А вот допустим для текста вывести в одном поле в таблице или в запросе "Красный" - красным цветом, "Зеленый" - зеленым. Вот это как, я не знаю. И думаю возможно ли такое вообще
Иначе зачем майкрософту Format Condition например?
Ну так "условное форматирование" ещё никто не отменял. :)
В отчётах например есть событие "форматирование", там в зависимости от значения поля можно и цветами баловаться.
...
Рейтинг: 0 / 0
интересные факты / наблюдения / анализ чужих и собственных решений
    #37751293
ALEXIS_22
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
studieren
Да, в отчетах это без проблем.
...
Рейтинг: 0 / 0
интересные факты / наблюдения / анализ чужих и собственных решений
    #37751363
вадя
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ALEXIS_22studieren

Просто раскрасить поля в запросе это одно. Но практическая ценность будет намного выше если как-то задавать формат в зависимости от значения в поле. Пока не выходит. Через iif пробую.

если разговор о ленточных формах - то нет проблем. расскрасить можно как угодно
...
Рейтинг: 0 / 0
интересные факты / наблюдения / анализ чужих и собственных решений
    #37752698
ALEXIS_22
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
вадяесли разговор о ленточных формах - то нет проблем. расскрасить можно как угодно
Да мне обычного условного форматирования для ленточных форм хватало (как правило). Если не хватало то FlexGrid использовал.
Кажется видел где-то пример раскраски для ленточных форм без УФ. Там действительно ограничений 3 условий нет.

Возвращаясь к основной теме про форматирование полей в запросе\таблице. Совершенно недавно видел пример использования такого форматирования полей в запросе для создания "цветных" ListBox и ComboBox. Даже его скачал. Первый раз открыл - подивился оригинальности, далее отложил. В свете этой теме решил к нему вернуться. И как не старался более эти цветные поля увидеть не смог. Значения в полях списка, к которым были применены форматы просто не видны. Пробовал в ACSE 2003 (SP3).
Если кто-то из обитателей форума знает о каком примере идет речь поделитесь были ли у кого с ним какие-то проблемы с реализацией такого списка.

Весь комизм текущей ситуации заключается в том, что я сейчас не имею возможности этот пример приложить. Попробую немного позже в инете снова его взять. Тогда приложу.
...
Рейтинг: 0 / 0
интересные факты / наблюдения / анализ чужих и собственных решений
    #37753191
ALEXIS_22,

12190877 ?
...
Рейтинг: 0 / 0
интересные факты / наблюдения / анализ чужих и собственных решений
    #37753225
ALEXIS_22
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
13-й квартал ALEXIS_22,
12190877?

Ну да! Он самый. У меня на одном компе отработал, на двух других нет.
Сейчас сижу далеко. В инет урывками поглядываю. Офиса здесь нет, проверить еще раз не могу. Только у себя - завтра к вечеру.
Как говорит Осьменоги - "ыыы-ыы-ы"
...
Рейтинг: 0 / 0
интересные факты / наблюдения / анализ чужих и собственных решений
    #37771619
studieren
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вот здесь есть старинный код, с помощью которого можно узнать список названия компьютеров, подключённых к указанному файлу базы данных.
Sub ShowUserRosterMultipleUsers()
Dim cn As New ADODB.Connection
Dim cn2 As New ADODB.Connection
Dim rs As New ADODB.Recordset
Dim i, j As Long

cn.Provider = "Microsoft.Jet.OLEDB.4.0"
cn.Open "Data Source=c:\Northwind.mdb"

cn2.Open "Provider=Microsoft.Jet.OLEDB.4.0;" _
& "Data Source=c:\Northwind.mdb"

' The user roster is exposed as a provider-specific schema rowset
' in the Jet 4 OLE DB provider. You have to use a GUID to
' reference the schema, as provider-specific schemas are not
' listed in ADO's type library for schema rowsets

Set rs = cn.OpenSchema(adSchemaProviderSpecific, _
, "{947bb102-5d43-11d1-bdbf-00c04fb92675}")

'Output the list of all users in the current database.

Debug.Print rs.Fields(0).Name, "", rs.Fields(1).Name, _
"", rs.Fields(2).Name, rs.Fields(3).Name

While Not rs.EOF
Debug.Print rs.Fields(0), rs.Fields(1), _
rs.Fields(2), rs.Fields(3)
rs.MoveNext
Wend

End Sub

Даже при аварийном завершении видимо Access успевает "отметится" как вылетевший и поэтому в списке пользователей не выходит (что вообщем-то хорошо!). Но!!! Если всё-таки Access не успеет подать сигнал о завершении, к примеру если внезапно вырубить от электропитания или выдернуть сетевой шнур (что не сделаешь ради эксперимента ), то из списка всё-таки не будет уходить.
Я решил в конце вместо "Debug.Print" склеить в строковую переменную и выдать сообщение через MsgBox. Типа так:
Код: vbnet
1.
2.
3.
4.
5.
6.
7.
Dim strUsers As String
While Not rs.EOF
    strUsers = strUsers & rs.Fields(0) & "   " &  rs.Fields(1) & "   " & _
        rs.Fields(2) & "   " & rs.Fields(3) & vbCrLf
    rs.MoveNext
Wend
MsgBox strUsers


Вот тут к моему удивлению обнаружил, что получаю имя компьютера только 1-пользователя! И ничего более!
Начал экспериментировать и выяснять причину. Оказывается "rs.Fields(0)" здесь возвращает имя компьютера и сразу же за ним символ Chr(0) и далее ровно столько пробелов, чтобы в общей сложности должно получиться 32 символа. И у этого символа Chr(0) (так сказать vbNullChar) есть странная особенность:
все символы после Chr(0) при вызове MsgBox или InputBox пропадают.
Код: vbnet
1.
2.
3.
4.
5.
Dim S As String

S = "Test is " & Chr(0) & " test!"
MsgBox S
S = InputBox(S, S)
...
Рейтинг: 0 / 0
интересные факты / наблюдения / анализ чужих и собственных решений
    #37792018
studieren
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Создал запрос, где в параметрах сразу назначаю значение с помощью DLookUp:
Код: sql
1.
2.
3.
PARAMETERS A Text ( 255 ) = DLOOKUP("Name", "MSysObjects");
SELECT TOP 1 A AS X
FROM MSysObjects;


Сохранил и дал название "Запрос1". Вот теперь в так называемых "статистических функциях по подмножеству" (таких как DCount, DLookUp и т.д.) не возможно использовать этот запрос.
Код: vbnet
1.
?DCount("*", "Запрос1")


!---------------------------
Microsoft Visual Basic
---------------------------
Run-time error '2001':

Предыдущая операция прервана пользователем.
---------------------------
ОК Справка
---------------------------

А если использовать этих функций не в параметрах, а в SELECT или WHERE, то такой ошибки не получаем:
Код: sql
1.
2.
3.
SELECT TOP 1 Name
FROM MSysObjects
WHERE DCount("*", "MSysObjects")>0;



Код: vbnet
1.
2.
?DLookup("Name", "Запрос1")
Tables
...
Рейтинг: 0 / 0
интересные факты / наблюдения / анализ чужих и собственных решений
    #37822393
studieren
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Все программисты MS Access (да и не только Access) всячески стараются не работать с таблицами или запросами напрямую, в смысле не дают прямой доступ пользователям к таблицам / запросам. Почему? Ответ очевиден, полное отсутствие программного контроля, т.е. отсутствие "событий".
Когда база разрастается, и там появляются множества таблиц справочников, то создавать отдельную форму на все таблицы (или запросы) порой нет времени (или просто лень).
Когда "вручную" открываем таблицу (или запрос), то действительно сталкиваемся полным отсутствием всяких событий, на которых реагирует программа. Но если открывать программно, то оказывается, хотя бы на время можно искусственно создавать событие!
Приведу такой пример: допустим, пользователь работает с какой-то формой и там есть некий код справочника. Появилась необходимость ввода нового кода справочника. Что он должен делать? Открыть таблицу справочников и добавить новую запись. Находясь в форме, он может дважды щёлкнуть поле для кода справочника и тут программа может открыть таблицу, причём параллельно создать некоторые события таблицы. Ну скажем "BeforeUpdate", "AfterUpdate", "OnClose" и т.д.
Делается это очень и очень просто.
Для эксперимента создаём процедуру, где открываем таблицу и создаём временные события для таблицы.
Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
Sub OpenTableWithEvents()
     DoCmd.OpenTable "Table1"
     With Screen.ActiveDatasheet
          .BeforeUpdate = "=MsgBox(""BeforeUpdate"")"
          .AfterUpdate = " =MsgBox(""AfterUpdate"")"
          .OnMouseMove = "=MsgBox(""OnMouseMove"")"
          .MouseWheel = "=MsgBox(""MouseWheel"")"
          .OnClose = "=MsgBox(""OnClose"")"
     End With
End Sub


После закрытия таблицы, увы, все эти события исчезнут.
Разумеется, вместо "MsgBox" можно написать собственную функцию, да и вместо таблицы можно и запрос на выборку точно таким же образом открывать. Тогда и можно программно контролировать, словно работаем с табличной формой.

P.S. Я конечно же не рекламирую работу с таблицами и запросами напрямую. Я тоже сторонник закрытия доступа к рядовым пользователям. Но иногда если есть необходимость, то могу поступать именно таким образом, т.е. программно открыть, чтобы программно же и контролировать действия пользователя. :)
...
Рейтинг: 0 / 0
интересные факты / наблюдения / анализ чужих и собственных решений
    #37822466
alvk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
studieren,

табличную форму для справочника сделать -> 3 - 5 минут.
...
Рейтинг: 0 / 0
интересные факты / наблюдения / анализ чужих и собственных решений
    #37822567
Фотография Старый ворчун
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alvkstudieren,

табличную форму для справочника сделать -> 3 - 5 минут.
Не это главное.
Вы, наверное, в курсе, что в качестве SourceObject подчиненной формы можно использовать таблицу или запрос?
Это бывает очень удобно использовать. Из одной формы можно сделать множество справочников. Решение studieren позволяет создавать события для такой подчиненной формы. Это, по крайней мере, интересно. А для профессионала дополнительный инструмент.
...
Рейтинг: 0 / 0
интересные факты / наблюдения / анализ чужих и собственных решений
    #37822593
alvk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Старый ворчун,

Старый ворчунчто в качестве SourceObject подчиненной формы можно использовать таблицу или запрос

я такой вариант не приемлю, мне он не нравится.
...
Рейтинг: 0 / 0
25 сообщений из 280, страница 7 из 12
Форумы / Microsoft Access [игнор отключен] [закрыт для гостей] / интересные факты / наблюдения / анализ чужих и собственных решений
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]