powered by simpleCommunicator - 2.0.51     © 2025 Programmizd 02
Форумы / Microsoft Access [игнор отключен] [закрыт для гостей] / интересные факты / наблюдения / анализ чужих и собственных решений
25 сообщений из 280, страница 4 из 12
интересные факты / наблюдения / анализ чужих и собственных решений
    #37345302
попробуй скачать файл отсюда или найди его на msdn или support.microsoft.com

http://www.sql.ru/forum/actualutils.aspx?action=gotomsg&tid=492885&msg=4900746
...
Рейтинг: 0 / 0
интересные факты / наблюдения / анализ чужих и собственных решений
    #37345551
studieren
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
сосед-акцессник,

Спасибки Вам и "бабай". Интересный файл, там много чего интересного подробно написано.
Читаю и изучаю.
...
Рейтинг: 0 / 0
интересные факты / наблюдения / анализ чужих и собственных решений
    #37348147
studieren
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Как программно отправить на печать только определенные страницы отчета с заданным количеством экземпляров?

Допустим, имеется отчёт с несколькими страницами. Скажем - 100 страниц. Нам нужно напечатать все страницы начиная с 10 по 20 в 2-х экземплярах. Как это сделать программно?

Для этого создадим следующую VBA функцию:
Код: plaintext
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.
Function PrintReport(ReportName As String, _
        FirstPage As Integer, LastPage As Intiger, CopyQuantity As Byte)
    Dim blnIsLoaded As Boolean
    
    ' Следует проверить существование отчёта.
    ' Если произойдёт ошибка 2467, значит отчёт не существует.
    On Error Resume Next
    blnIsLoaded = CurrentProject.AllReports(ReportName).IsLoaded
    If Err.Number =  2467  Then
        MsgBox "Отчёт """ & ReportName & """ не существует в базе данных! " & _
            "Проверьте название отчёта.", vbInformation
        Exit Function
    ElseIf Err.Number <>  0  Then
        MsgBox Err.Description, vbInformation
        Exit Function
    End If
    
    ' Проверим числа
    If FirstPage <=  0  Or LastPage <=  0  Or CopyQuantity =  0  Then
        MsgBox "Введите положительное целое число в качестве начальной / последней " & _
            "страницы / количества эксземпляров отчёта.", vbInformation
        Exit Function
    ElseIf FirstPage > LastPage Then
        MsgBox "Номер начальной страницы не должен быть больше порядкового номера " & _
            "конечной страницы.", vbInformation
        Exit Function
    End If
    
    If blnIsLoaded = False Then
        DoCmd.OpenReport ReportName, acPreview, , , acHidden
    End If
    
    DoCmd.PrintOut acPages, FirstPage, LastPage, , CopyQuantity, False
    If blnIsLoaded = False Then
        DoCmd.Close acReport, ReportName
    End If
End Function

Код: plaintext
PrintReport "Отчёт",  10 ,  20 ,  2 
...
Рейтинг: 0 / 0
интересные факты / наблюдения / анализ чужих и собственных решений
    #37354519
studieren
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник

Очепятка в предыдущем посте. :)
Вместо "Intiger" читать как "Integer" в параметрах функции.

Как известно в VBA есть стандартный MsgBox.
В принципе и в библиотеке "WSript.Shell" есть свой MsgBox.
Код: plaintext
Function MsgBoxExt(Prompt As String, Optional Buttons As VbMsgBoxStyle = vbOKOnly, _\n        Optional Title, Optional ByVal SecondsToWait As Integer) As Integer\n    \' Аналог MsgBox с возможностью самовыключения.\n    \' Возвращает код нажатой клавиши или -1, если время ожидания исчерпано.\n    Dim wshShell As Object\n    \n    Set wshShell = VBA.CreateObject("WScript.Shell")\n    MsgBoxExt = wshShell.PopUp(Prompt, SecondsToWait, Title, Buttons)\nEnd Function

Есть также у Win API свой MsgBox.
Код: plaintext
Private Declare Function MessageBox _\n        Lib "user32.dll" Alias "MessageBoxA" ( _\n        ByVal hWnd As Long, _\n        ByVal lpText As String, _\n        ByVal lpCaption As String, _\n        ByVal wType As Long) As Long\n\nFunction WinAPI_MsgBox(Prompt As String, Title As String, WinType As Long) As Long\n    WinAPI_MsgBox = MessageBox( 0 &, Prompt, Title, WinType)\nEnd Function

MsgBox в WinAPI и в WSript.Shell в отличии от стандартного MsgBox в VBA не модальный, т.е. даже когда Вы получаете MsgBox и ещё не нажали на кнопку, то Вы можете параллельно запускать любую процедуру/функцию и VBA параллельно будет выполнять. Но только клавиша F11 при этом не работает. :)


P.S. Случайно наткнулся на топик MsgBox на нерусском в русской версии win и MA?, где уважаемый Бенедикт предложил способ вывода текста MsgBox на любом языке (хоть на арабском).
Код уважаемого Бенедикта
Код: plaintext
Private Declare Function MessageBoxW Lib "user32" ( _\n   ByVal hWnd As Long, ByVal lpText As String, _\n   ByVal lpCaption As String, ByVal wType As VbMsgBoxStyle) As VbMsgBoxResult\n\nSub Hello()\n MessageBoxW  0 , _\n             StrConv("!" & ChrW(&HFE8E) & ChrW(&HFE92) & ChrW(&HFEA3) & _\n                     ChrW(&HFEAE) & ChrW(&HFEE3), vbUnicode), _\n             StrConv("Мархаба!", vbUnicode), _\n             vbExclamation + vbMsgBoxRight + vbMsgBoxRtlReading\nEnd Sub
...
Рейтинг: 0 / 0
интересные факты / наблюдения / анализ чужих и собственных решений
    #37363099
studieren
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Чтобы в запросах произвести условную сортировку, т.е. если выполняется 1-условие, то 1-блок данных сортируется первым, если 2-условие, то 2-блок и т.д., обычно пользуются функцией IIf. Что-то вроде этого:
Код: plaintext
1.
2.
SELECT Name
FROM MSysObjects AS O
ORDER BY IIf(Name='Tables',  1 , IIf(Name='Forms',  2 , IIf(Name='Reports',  3 ,  4 )))
Оказывается в MS Access этот же запрос можно запустить и без IIf. Вроде так:
Код: plaintext
1.
2.
SELECT Name
FROM MSysObjects AS O
ORDER BY Name='Tables', Name='Forms', Name='Reports';
С другой стороны т.к. здесь использовано единственное поле "Name", то можно здесь использовать IN и так:
Код: plaintext
1.
2.
SELECT Name
FROM MSysObjects AS O
ORDER BY Name IN ('Tables', 'Forms', 'Reports');
Но только в таком случае порядок следования записей будет не так, как в предыдущих запросах, т.е. не 'Tables', 'Forms', 'Reports', а 'Forms', 'Reports', Tables' (т.е. сами значения также будут отсортированы).

Есть ещё 1 нюанс: если таблица не "родная" для Access, а линкованная через ODBC (скажем таблица SQL Server), то такой номер не проходит, произойдёт ошибка:
Код: plaintext
1.
2.
SELECT Customer
FROM dbo_Customer
ORDER BY Customer IN ('Firma X', 'Firma Y', 'Firma Z');
[Microsoft][ODBC SQL Server Driver][SQL Server]Incorrect syntax near the keyword IN ...
В таком случае специально нужно использовать функцию, которая отсутствует на стороне SQL Server, и тогда запрос будет работать на УРА:
Код: plaintext
1.
2.
SELECT Customer
FROM dbo_Customer
ORDER BY Nz(Customer) IN ('Firma X', 'Firma Y', 'Firma Z');
...
Рейтинг: 0 / 0
интересные факты / наблюдения / анализ чужих и собственных решений
    #37364704
studieren
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вот здесь показан способ перехвата нажатия на кнопку меню. В качестве примера показан случай перехвата сортировки:
Код, который ловит событие нажатие кнопки сортировки


1. включите ссылку на библиотеку офис
2. в начале модуля формы :

Private WithEvents SortACBtn As Office.CommandBarButton
Private WithEvents SortDeBtn As Office.CommandBarButton

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
Private Sub SortACBtn_Click(ByVal Ctrl As Office.CommandBarButton, CancelDefault As Boolean)  
    On Error Resume Next
    'CancelDefault = True - если вместо сортировки своя процедура'  
    MsgBox "Сортировка по возрастанию "  
End Sub
 
Private Sub SortDeBtn_Click(ByVal Ctrl As Office.CommandBarButton, CancelDefault As Boolean)  
    MsgBox "Сортировка по Убыванию "  
End Sub
 
Private Sub Form_Load()  
    Set SortACBtn = CommandBars.FindControl(id:= 210 )  
    Set SortDeBtn = CommandBars.FindControl(id:= 211 )  
End Sub

Там же имеется таблица с указанием ID контролов меню.
Я по аналогии попробовал блокировать FIND (найти), т.е. если пользователь захочет найти запись, то я программно хочу заменить "Поиск" на "Фильтр", ибо как известно поиск работает значительно медленнее чем фильтр.
Но почему-то код, прекрасно блокирующий сортировку, не хочет блокировать поиск.
Что здесь не так?
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
Private WithEvents FindBtn As Office.CommandBarButton

Private Sub FindBtn_Click(ByVal Ctrl As Office.CommandBarButton, CancelDefault As Boolean)
    On Error Resume Next
    CancelDefault = True
    MsgBox "Тест."
End Sub

Private Sub Form_Load()
    Set FindBtn = CommandBars.FindControl(Id:= 5905 )  ' Здесь также попробовал 141
End Sub
Т.е. если пользователь захочет нажать на Ctrl+F или использовать меню "Правка" ==> "Найти...", то здесь хотелось бы получить сообщение "Тест".
Видимо здесь проблема с Id контрола. Как найти правильный Id?
...
Рейтинг: 0 / 0
интересные факты / наблюдения / анализ чужих и собственных решений
    #37364739
Фотография nord-woolf
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
С id=141 клик кнопки меню отлавливает, а комбинацию Ctrl+F - фиг. (А2003)
...
Рейтинг: 0 / 0
интересные факты / наблюдения / анализ чужих и собственных решений
    #37365102
studieren
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
nord-woolfС id=141 клик кнопки меню отлавливает, а комбинацию Ctrl+F - фиг. (А2003)
Thank you! :-))

Ну тогда сделаю 141 для перехвата меню и параллельно буду перехватывать комбинацию клавиш Ctrl + F.

Ещё 1 вопрос: можно ли переделать данный код так, чтобы возможно было позднее связывание, т.е. без подключения к MS Office?
Пробовал разные варианты, но что-то у меня не получается.


P.S. А как обстоят дела в А2007 и в А2010? Был бы признателен ежели кто-нибудь напишет будет ли работать данный код в этих версиях.
...
Рейтинг: 0 / 0
интересные факты / наблюдения / анализ чужих и собственных решений
    #37365151
Фотография nord-woolf
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
studieren,
С подпиской на события позднее связывание не годится.
Нужна типизированная переменная соответствующего класса.
...
Рейтинг: 0 / 0
интересные факты / наблюдения / анализ чужих и собственных решений
    #37370747
studieren
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Если хотим узнать версию Windows, вызвав диалоговое окно "About", то можем использовать вот такой код:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
Private Declare Function ShellAbout _
        Lib "shell32.dll" Alias "ShellAboutA" ( _
        ByVal hWnd As Long, _
        ByVal szApp As String, _
        ByVal szOtherStuff As String, _
        ByVal hIcon As Long) As Long

Private Sub ShowAbout()
    ShellAbout  0 &, "", "",  0 &
End Sub


Оказывается в данном диалоговом окне можно кое-что добавить. Что то вроде этого:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
Private Declare Function ShellAbout _
        Lib "shell32.dll" Alias "ShellAboutA" ( _
        ByVal hWnd As Long, _
        ByVal szApp As String, _
        ByVal szOtherStuff As String, _
        ByVal hIcon As Long) As Long

Private Sub ShowAbout()
    ShellAbout _
         0 &, _
        "Заголовок и 1-строка", _
        "Здесь напишем какой-нибудь текст, который будет " & _
            "выходить где-то в середине." & vbCrLf, _
         0 &
End Sub


Правда маловато текста умещается. Для заголовка и первой строки - всего лишь 1 строка, а для "середины" - 2 строки. :)

Здесь же можно ещё добавить иконку.
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
Private Declare Function ShellAbout _
        Lib "shell32.dll" Alias "ShellAboutA" ( _
        ByVal hWnd As Long, _
        ByVal szApp As String, _
        ByVal szOtherStuff As String, _
        ByVal hIcon As Long) As Long
Private Declare Function LoadIcon _
        Lib "user32.dll" Alias "LoadIconA" ( _
        ByVal hInstance As Long, _
        ByVal lpIconName As Long) As Long

Private Sub ShowAbout()
    ShellAbout _
         0 &, _
        "Что это такое?", _
        "Test is test!" & vbCrLf, _
        LoadIcon( 0 &,  32514 &)
End Sub
...
Рейтинг: 0 / 0
интересные факты / наблюдения / анализ чужих и собственных решений
    #37371966
alvk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
studieren,

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

Просто "спортивный интерес". Оказывается и такое возможно. :))
...
Рейтинг: 0 / 0
интересные факты / наблюдения / анализ чужих и собственных решений
    #37372231
studieren
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Есть 1 топик: Вопросы по форматированию полей .
Там вопрос № 1 гласит так:
В "Word"е имеется возможность выравнивания текста по ширине (в VBA ".ParagraphFormat.Alignment = wdAlignParagraphJustify"). В "Access"е также имеется свойство полей "Выравнивание текста" (TextAlign), где можно присвоить значение 4 (Distribute), после чего текст будет выровнен по ширине. Но имеется один недостаток: если последняя строка состоит из 1 или 2 слов, то Access расширит текст чуть ли не по буквам. А это в официальных документах (таких как контракт) не допустимо!
Как же сделать так, чтобы последнюю строку "Access" не трогал так же как в "Word"е?

В этом топике есть пост nord-wolf 9510505 , где в приложенном файле имеется код, который и расширяет текст. Однако есть небольшие недостатки:
I) если текст имеет перевод строки (Chr(13) + Chr(10)), то выглядит отчёт немного не так как надо;
II) высота поля должна быть неизменной, ну а если в деталях отчёта будет выходить несколько записей и если высота полей нефиксированная, то в отчёте будет выходить либо пустота между записями (если мы увеличили с запасом высоту поля), либо "пропадают" строки (что конечно же не допустимо). Проблема в том, что если свойство поля "Visible" = False, то высота поля станет неизменной даже если свойство "Расширение" (CanGrow) имеет значение "Да".
2-проблему можно решить только в том случае, если сделать фон и шрифт поля прозрачным и тогда можно будет свойство поля "Вывод на экран" (Visible) указать как true. К сожалению, я пока не смог решить это. А вот для того, чтобы решить 1-проблему я немного изменил код nord-wolf (главное изменение: я не стал расширять текст, а расширил пробелы между текстами как это делает Word) и у меня получился такой вариант:
Этот код можно разместить в модуле.
Код: plaintext
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.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
' Объявляем модульные переменные для расширения текста в Textbox по ширине _
  на подобие MS Word.
Private MaxWidth As Single  ' для фиксации длины текстового поля
Private sngX As Single, sngY As Single ' для определения координаты

Const SP As String = " " ' разделитель слов

' Идея процедуры заключается в следующем: _
  текстовое поле должно быть скрытым (т.е. свойство Visible = False), оно _
  необходимо нам разве что для измерения текста, а сам текст будет _
  воссоздан с помощью метода "Print" объекта "Report".
Public Sub TextAlign(Rpt As Access.Report, TextboxName As String)
    Dim ArrWords As Variant ' для массива строк
    Dim strPrint As String, strTemp As String
    Dim i As Integer
    
    With Rpt.Controls.Item(TextboxName)
        If IsNull(.Value) = True Or Len(.Value) =  0  Then Exit Sub
        ' Распределяем текст поля на массив строк с помощью функции "Split" и при _
          этом не укажем параметр функции "limit". Из-за отсутствия параметра _
          "limit" получим ровно столько элементов массива, сколько пробелов в _
          тексте +  1 .
        ArrWords = Split(Replace(.Value, vbCrLf, SP & Chr( 13 ) & SP), SP)
        
        ' Максимальная длина строк не может быть больше ширины поля. Здесь следует _
          "запомнить" ширину поля, чтобы в условиях IF можно было сравнивать ширину _
          текста.
        MaxWidth = .Width
        
        ' Здесь зафиксируем координаты текстового поля.
        sngX = .Left
        sngY = .Top
        
        ' Чтобы точно измерить длину текста с помощью метода "TextWidth" _
          следует свойства шрифта текстового поля присвоить свойствам шрифта _
          самого отчёта.
        Rpt.FontName = .FontName
        Rpt.FontSize = .FontSize
        Rpt.FontBold = .FontBold
        Rpt.FontItalic = .FontItalic
    End With
    
    ' Теперь прокручиваем массив и обратно собираем слова
    For i =  0  To UBound(ArrWords)
        strPrint = strPrint & ArrWords(i) & SP
        
        If i < UBound(ArrWords) Then
            ' Если текст содержит перевод строки, т.е. Chr(13), _
              то следует разбить на  2  текста и распечатать отдельно. _
              Иначе отчёт будет выглядит непрезентабельно. Поэтому _
              проверяем имеется ли символ Chr( 13 )
            If ArrWords(i +  1 ) <> Chr( 13 ) Then
                ' Добавив очередное слово из массива проверяем длину текста
                strTemp = strPrint & ArrWords(i +  1 )
                If Rpt.TextWidth(strTemp) > MaxWidth Then
                    ' Полученный текст больше длины текстового поля. Поначалу _
                      убираем правый, крайный пробел.
                    strPrint = RTrim$(strPrint)
                    ' Теперь с помощью процедуры "PrintText" печатаем текст. _
                      Необходимо передать процедуре количество пробелов для _
                      параметра "SpacesQuantity", чтобы процедура могла чуть-чуть _
                      расширить пробелы, чтобы выровнить текст. Для этого идеально _
                      подходит "i". Если i =  0 , то это первое слово и _
                      соответственно пробела пока нет. А если i =  1 , то слов  2  и _
                      соответственно пробел  1  и т.д.
                    PrintText Rpt, strPrint, True
                    strPrint = ""
                    strTemp = ""
                End If
            Else
                strTemp = RTrim$(strTemp)
                PrintText Rpt, strTemp, False
                strPrint = ""
                strTemp = ""
                i = i +  1 
            End If
        Else
            ' Если процедура дошла до этой точки, то это означает, что _
              мы дошли до последнего элемента массива. Здесь также _
              убираем крайний правый символ.
            strPrint = RTrim$(strPrint)
            ' Запускаем процедуру "PrintText"
            If Len(strPrint) >  0  Then
                PrintText Rpt, strPrint, False
            End If
            strPrint = ""
            strTemp = ""
        End If
    Next i
End Sub
Private Sub PrintText(Rpt As Access.Report, strPrint As String, ExtendText As Boolean)
    ' Процедура не расширяет все символы текста, как это делает Access, а _
      расширяет пробелы, как это делает Microsoft Word. Так более красивее _
      выглядят отчёты.
    Dim ArrWords As Variant, AddlSpace As Single, x As Single, i As Byte
    
    If Len(strPrint) =  0  Then Exit Sub
    
    ArrWords = Split(strPrint, SP)
    ' А если количество пробелов указано, то следует найти недостающее _
      пространство (т.е. разница между текстом "strPrint" и длиной _
      текстового поля - maxWidth) и поделить на количество пробелов. _
      При распечатке между слов следует добавить полученное число, _
      чтобы ровномерно расширить пробелы.
    If UBound(ArrWords) >  0  And ExtendText = True Then
        AddlSpace = (MaxWidth - Rpt.TextWidth(strPrint)) / UBound(ArrWords)
    End If
    x = sngX
    ' Заново прокручиваем массив строк, но на этот раз чтобы распечатать.
    For i =  0  To UBound(ArrWords)
        ' Следует определиться с координатами текста
        Rpt.CurrentX = x
        Rpt.CurrentY = sngY
        Rpt.Print ArrWords(i)
        x = x + Rpt.TextWidth(ArrWords(i) & SP) + AddlSpace
    Next i
    
    ' Для следующей строки следует вертикаль сдвинуть вниз.
    sngY = sngY + Rpt.TextHeight(strPrint)
End Sub

А в модуле отчёта можно указать примерно такой код
Код: plaintext
1.
2.
3.
Private Sub Details_Format(Cancel As Integer, FormatCount As Integer)
    TextAlign Me, "Text1"
    TextAlign Me, "Text2"
End Sub
Здесь "Text1" и "Text2" название полей textbox.


P.S. Код в принципе рабочий. Как только смогу решить и 2-проблему выложу здесь.
Наверное Бенедикт или кто-то ещё из экспертов знает как сделать фон поля и шрифт сделать прозрачным, а не белым. Если подскажите как это сделать, был бы признателен. :)

И ещё! Спасибо nord-wolf за его код.
Если у кого-то более "продвинутый код", please поделитесь!
...
Рейтинг: 0 / 0
интересные факты / наблюдения / анализ чужих и собственных решений
    #37379826
studieren
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Не помню откуда, но как то мне попался код, который запрещает открытие одной и той же базы 2 раза. А код достаточно простой, многократно использовал в разных проектах и ничего, работает. :)
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
Dim FirstRunnedApp As Object, byteCheck As Byte

Set FirstRunnedApp = GetObject(CurrentProject.FullName)
If Application.hWndAccessApp <> FirstRunnedApp.hWndAccessApp Then
    byteCheck = Eval("MsgBox(""ОШИБКА!!!@Нельзя открывать базу данных 2 и более раза!!!@""," & _
        vbExclamation & ",""Системная ошибка!"")")
    FirstRunnedApp.DoCmd.RunCommand  10   ' acCmdAppMaximize = 10
    Set FirstRunnedApp = Nothing
    Application.Quit
End If
...
Рейтинг: 0 / 0
интересные факты / наблюдения / анализ чужих и собственных решений
    #37409030
studieren
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Бывают случаи, когда в подчинённой таблице необходимо ввести не все значения ключевого поля главной таблицы, а избранные. В таких случаях часто в главной таблице создают дополнительное поле - некий признак: если признак соответствует каким-то требованиям, то значения ключевого поля только данной записи может быть в подчинённой таблице.
Чтобы было более понятно приведу пример:
Допустим есть таблица "tblCustomer", где ключевое поле "CustomerID". Есть также подчинённая таблица "tblBonus", где также имеется поле "CustomerID", куда необходимо ввести код не любого клиента, а только "VIP" клиентов. В таких случаях часто программисты создают дополнительное логическое поле "VIP" в таблице "tblCustomer" и создают Check Constraint (или триггер если таблицы находятся в "реальных" РСУБД), чтобы контролировать ввод клиентов из категории "VIP". А в Access многие вообще не возятся с Check Constraint, а в включают проверку на событие BeforeUpdate.

А существует ли другой способ без Check Constraint, триггеров и проверок на событие BeforeUpdate, но чтобы "железно" гарантировать ввод избранных значений ключевого поля (например, только VIP клиентов)?
Оказывается есть и для этого зачастую даже не требуется создание отдельного поля - признак в главной таблице. Итак, следует создать дополнительную таблицу "tblVIP", где будет единственное поле "CustomerID" и необходимо связать с главной таблицей "tblCustomer" по принципу "один к одному", при этом таблица "tblCustomer" должна находиться "левее". В таблицу "tblVIP" будем вводить код только VIP клиентов. А подчинённую таблицу "tblBonus" необходимо связать не с главной таблицей "tblCustomer", а с таблицей "tblVIP".
Вот теперь без всяких Check Constraint, "триггеров" и проверок на событие BeforeUpdate "железно" можем гарантировать "избранных" значений ключевого поля.

P.S. Связь "1 к 1" редко бывает полезным, но этот случай пожалуй исключение.
...
Рейтинг: 0 / 0
интересные факты / наблюдения / анализ чужих и собственных решений
    #37414662
Komil_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Часто на форуме спрашивают как перевернуть текст на 90 градусов. (Сам тоже как-то спрашивал :), но теперь-то знаю как это просто.)
В Аксессе есть конечно свойство "По вертикали", но оно переворачивает текст на 270 градусов.
Как же всё-таки перевернуть на 90 градусов?
Как правило, переворачивать текст следует в заголовках столбцов отчёта (т.е. в надписях, находящихся в верхнем колонтитуле или же в заголовке отчёта). А в самих деталях отчёта редко такое требуется. Самый простейший способ это создание нужного заголовка в виде таблицы в MS Excel. После этого просто копируем таблицу и в отчете Аксесса в режиме конструктора в верхнем колонтитуле или же в заголовке отчёта вставим из буфера обмена.
Всё просто и ни одной строчки кода! :)
Есть конечно сложные коды Лебенса (мне посоветовали тогда именно их 9504909 ), но зачем когда имеется самый простой способ. :)
...
Рейтинг: 0 / 0
интересные факты / наблюдения / анализ чужих и собственных решений
    #37414688
alvk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Komil_,

а вот тут можно и спотыкнуться, когда параметры страницы менять будешь
...
Рейтинг: 0 / 0
интересные факты / наблюдения / анализ чужих и собственных решений
    #37428353
studieren
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Я раньше думал, что основное преимущество ADO перед DAO заключается в универсальности подключения к любой СУБД, находясь где угодно. Да хоть в Excel'е или в Word'е можем подключаться к Oracle, MySQL и т.п., а не только Access или SQL Server. Я раньше полагал, что DAO предназначен только для работы в Access и минуя ее не может подключится к другим СУБД. В смысле в Access'е создаём линкованную таблицу или запрос к серверу и только потом можем работать в других СУБД. Но как я понял позже, я ошибся, DAO тоже умеет работать с другими СУБД, минуя Access, главное - на клиентском компьютере должны быть соответствующие драйверы. Ещё одним большим сюрпризом для меня стало то, что объект RecordSet в DAO умеет работать и "чужим" синтаксисом (словно запрос к серверу), а не только синтаксисом Jet SQL. Но только для этого придётся "колдовать" и "шаманить" слегка. :)
Из-за чистого спортивного интереса стал экспериментировать в DAO.
Вот примерчик как можно подключиться к SQL Server (данный код можно использовать и в Excel'е):
Код: plaintext
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.
38.
39.
40.
41.
42.
43.
44.
45.
46.
' Можно создать текст подключения через DSN
' Public Const ODBC As String = "ODBC;DSN=MyDSN";Database=MyDataBase;"
' Можно создать текст прямого подключения к серверу
Public Const ODBC As String = "ODBC;DRIVER=SQL Server;SERVER=MyServer,1433;" & _
    "DATABASE=MyDatabase;Trusted Connection=Yes;"

Sub Test()
    Dim Wrk     As DAO.Workspace
    Dim Cnnt    As DAO.Connection
    Dim DB      As DAO.Database
    Dim xQuery  As DAO.QueryDef
    Dim RecSet  As DAO.Recordset
    Dim strSQL  As String
    
    strSQL = "SELECT CAST(1.5 AS Int) AS Test"
    ' Если использовать OpenDatabase, то объект Recordset не сможет
    ' использовать напрямую синтаксис SQL Serverа, в таком случае
    ' придётся обратиться через запрос к серверу как в данном примере.
    Set DB = DBEngine.OpenDatabase("", _
        dbDriverCompleteRequired, True, ODBC)
    Set xQuery = DB.CreateQueryDef("")
    xQuery.Connect = ODBC
    xQuery.Sql = strSQL
    Set RecSet = xQuery.OpenRecordset
    MsgBox RecSet.Fields(0) & vbCrLf & _
        DB.Name & vbCrLf & _
        DB.Connect

    ' Чтобы "научить" Recordset к "чужому" синтаксису (словно запрос к
    ' серверу) придётся идти другим путём.
    Set Wrk = DBEngine.CreateWorkspace("", "", "", dbUseODBC)
    Set Cnnt = Wrk.OpenConnection("", dbDriverCompleteRequired, True, ODBC)
    Set RecSet = Cnnt.OpenRecordset(strSQL)
    MsgBox RecSet.Fields(0) & vbCrLf & _
        Cnnt.Database.Name & vbCrLf & _
        Cnnt.Connect
    Set Wrk = Nothing
    ' Нюанс: если обнулить объектную переменную Wrk, т.е. после
    ' "Set Wrk = Nothing" "Cnnt.Connect" вернёт ошибку!
    ' Поэтому вот этот код уже нельзя использовать!
    ' Debug.Print Cnnt.Connect
    
    Set Cnnt = Nothing
    Set RecSet = Nothing
    Set xQuery = Nothing
    Set DB = Nothing
End Sub

Возникает вопрос: а в чём всё-таки бесспорное преимущество ADO от DAO? Что же умеет ADO чего не умеет DAO?
Я знаю только то, что ADO "почти всё" умеет в стандарте ANSI92 SQL даже если сама база не переведена в этот стандарт (т.е. умеет запускать некоторые запросы на управления, которых DAO не может запускать без перехода в этот стандарт).
Ну и сам Microsoft вроде бы грозился убрать DAO в будущих версиях, мол устаревшая технология. По крайнем мере в А2007 пока DAO жив (из-за не имения А2010 не знаю как там).
А ещё в чём же преимущество?
...
Рейтинг: 0 / 0
интересные факты / наблюдения / анализ чужих и собственных решений
    #37428524
Фотография Sator Arepo
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
studieren.......................
Возникает вопрос: а в чём всё-таки бесспорное преимущество ADO от DAO? Что же умеет ADO чего не умеет DAO?
Я знаю только то, что ADO "почти всё" умеет в стандарте ANSI92 SQL даже если сама база не переведена в этот стандарт (т.е. умеет запускать некоторые запросы на управления, которых DAO не может запускать без перехода в этот стандарт).
Ну и сам Microsoft вроде бы грозился убрать DAO в будущих версиях, мол устаревшая технология. По крайнем мере в А2007 пока DAO жив (из-за не имения А2010 не знаю как там).
А ещё в чём же преимущество?
Да какой смысл разбирать две устаревшие технологии доступа к данным? Из спортивного интереса если только?
Могу подкинуть одно преимущество ADO (если конечно, не ошибаюсь): multiple recordsets. Эта возможность мне помогла добиться выполнения скрипта из нескольких SQL-команд в Jet-e, когда создавал для себя нечто вроде Query Analyzer.
...
Рейтинг: 0 / 0
интересные факты / наблюдения / анализ чужих и собственных решений
    #37428857
Guest33
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Если не ошибаюсь, второй вариант ОДБС подключения (через опенконнект) называется ODBC direct и в А2010 не поддерживается. Обнаружил, когда для пробы переводил свою программу с А2003 на А2010
...
Рейтинг: 0 / 0
интересные факты / наблюдения / анализ чужих и собственных решений
    #37428882
studieren
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Sator ArepoДа какой смысл разбирать две устаревшие технологии доступа к данным?
Разве технология ADO (ADODB/ADOX) уже устарела? У нее есть альтернатива?

Sator ArepoМогу подкинуть одно преимущество ADO (если конечно, не ошибаюсь): multiple recordsets.
Вы имеете ввиду NextRecordset или что-то другое?
...
Рейтинг: 0 / 0
интересные факты / наблюдения / анализ чужих и собственных решений
    #37428921
Фотография Sator Arepo
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
studierenSator ArepoДа какой смысл разбирать две устаревшие технологии доступа к данным?
Разве технология ADO (ADODB/ADOX) уже устарела? У нее есть альтернатива?

Sator ArepoМогу подкинуть одно преимущество ADO (если конечно, не ошибаюсь): multiple recordsets.
Вы имеете ввиду NextRecordset или что-то другое?
Да, NextRecordset.
Насчет "устаревшие" - может и погорячился. Альтернатив DAO/ADO для Аксесса в любом случае нет. Дык и Аксесс уже дедушка на пенсии - ADO.Net не для него.
...
Рейтинг: 0 / 0
интересные факты / наблюдения / анализ чужих и собственных решений
    #37428953
studieren
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вообще-то и в DAO есть NextRecordSet.

Значит единственное преимущество (по крайнем мере другого пока не вижу) - это умение запускать спец запросов на управление (например, создание Check Constraint).
Ну если ошибаюсь и всё-таки есть что-то, please напишите.
...
Рейтинг: 0 / 0
интересные факты / наблюдения / анализ чужих и собственных решений
    #37428958
Фотография Sator Arepo
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
studierenВообще-то и в DAO есть NextRecordSet.

Значит единственное преимущество (по крайнем мере другого пока не вижу) - это умение запускать спец запросов на управление (например, создание Check Constraint).
Ну если ошибаюсь и всё-таки есть что-то, please напишите.
А чего желтым цветом-то? Спасибо, я не знал - т.к. необходимости не было, а когда начинал изучать Аксесс, вовсю пропогандировался ADO.
Одно из многочисленных обсуждений
http://www.accessmonster.com/Uwe/Forum.aspx/access-ado/1780/ADO-vs-DAO
...
Рейтинг: 0 / 0
интересные факты / наблюдения / анализ чужих и собственных решений
    #37428972
Фотография Sator Arepo
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
studierenВообще-то и в DAO есть NextRecordSet.

Значит единственное преимущество (по крайнем мере другого пока не вижу) - это умение запускать спец запросов на управление (например, создание Check Constraint).
Ну если ошибаюсь и всё-таки есть что-то, please напишите.
вот еще интересное обсуждение
http://blogs.msdn.com/b/michkap/archive/2007/07/13/3849288.aspx
...
Рейтинг: 0 / 0
25 сообщений из 280, страница 4 из 12
Форумы / Microsoft Access [игнор отключен] [закрыт для гостей] / интересные факты / наблюдения / анализ чужих и собственных решений
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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