Форум программистов, компьютерный форум, киберфорум
Microsoft Access
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.92/64: Рейтинг темы: голосов - 64, средняя оценка - 4.92
Особый статус
 Аватар для FloppyDisc
623 / 221 / 164
Регистрация: 18.11.2015
Сообщений: 1,086

Создание таблицы посредством VBA

11.12.2017, 09:57. Показов 13503. Ответов 30
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Добрый день!

Скажите пожалуйста, у типов полей: BINARY, TINYINT, INTEGER, TINYINT, DECIMAL нельзя указать ограничение по длине?
Просто, например, в MySQL можно https://dev.mysql.com/doc/refm... rview.html
а что же JetSQL(?) что-то непонятки.

Это нужно, чтобы собрать CREATE TABLE в VBA, например этот кусок:
Visual Basic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
' Если тип поля является строкой
        If CreateTable!U_C_Type = "STRING" Then
        
            ' И если у него пустое значение длины устанавливаем тип MEMO
            If IsNull(CreateTable!N_Length) Then
                f = "memo"
            ' Иначе TEXT(LEN)
            Else
                f = "text(" & CreateTable!N_Length & ")"
            End If
            
        ' Иначе же просто определяем наж тип
        ElseIf (CreateTable!U_C_Type = "INTEGER" Or CreateTable!U_C_Type = "TINYINT" Or CreateTable!U_C_Type = "SMALLINT") Then
            f = CreateTable!U_C_Type
        Else
            f = CreateTable!U_C_Type & "(" & CreateTable!N_Length & ")"
        End If
Ничего умнее как перечислить все BINARY, TINYINT, INTEGER, TINYINT, DECIMAL в условии не придумал... Можно это реализовать красиво? На выходе должны быть правильно сформированные строки типа INTEGER либо VARCHAR(255)

з.ы. За U_C_Type, N_Length - не ругайте, препод так заставляет писать)
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
11.12.2017, 09:57
Ответы с готовыми решениями:

Вывод таблицы в Word посредством vba.
Доброго времени суток. Делаю отчет в Access кодом VBA и вывожу в вордовский документ. Подскажите код на создание таблицы таким же образом....

Создание таблицы средствами VBA
Здравствуйте, уважаемые пользователи, прошу помощи!!! Работаю в Аксесе, создал модуль по созданию новой таблицы в базе данных(текст...

Автоматическое создание формы на основе созданной таблицы в результате импорта данных (VBA)
Доброе время суток, Уважаемые! Подскажите, пожалуйста, решение задачи. Задача: Необходимо после импорта данный из разных однотипных...

30
Эксперт MS Access
 Аватар для Eugene-LS
13172 / 5869 / 1504
Регистрация: 05.10.2016
Сообщений: 16,488
11.12.2017, 10:17
Лучший ответ Сообщение было отмечено FloppyDisc как решение

Решение

Может поможет:
Простейший пример кода, который создает таблицу дней недели ("tempWeekDays") с порядковым номером в поле "DayID" и названием дня в поле "DayName"

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
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
Private Sub CreateWeekDaysTable()
'Создание Таблицы (Список дней недели)
'--------------------------------------------------------------------
Const strTableName As String = "tempWeekDays" 'Название таблицы
Dim tbl As TableDef       'объект таблица
Dim idx As Index          'объект индекс
Dim fld As Field          'объект поле
Dim rst As Recordset      'объект набор записей
Dim i As Integer          'счетчик дней
 
'Удаяем прошлое
    On Error Resume Next
    CurrentDb.TableDefs.Delete strTableName
    Err.Clear
    
On Error GoTo CreateWeekDaysTableErr
 
'создание объектной переменной таблицы, полей и индекса в ней
    Set tbl = CurrentDb.CreateTableDef(strTableName)
    With tbl
        .Fields.Append tbl.CreateField("DayID", dbLong)
        .Fields.Append tbl.CreateField("DayName", dbText, 20)
            'создание уникального индекса
            Set idx = .CreateIndex("Primary Key")
                With idx
                    'добавление поля в индекс
                    .Fields.Append .CreateField("DayID")
                    'Установка свойств индекса
                    .Unique = True   'Уникальный
                    .Primary = True  'Первичный
                End With
            .Indexes.Append idx
           'индекс создан
    End With
'Фактическое добавление таблицы из объектной переменной описанной выше
    CurrentDb.TableDefs.Append tbl
 
 
'Заполнение таблицы данными
    Set rst = CurrentDb.OpenRecordset(strTableName, dbOpenDynaset)
    With rst
        For i = 1 To 7
            .AddNew
            !DayID = i
            !DayName = DayName(i)
            .Update
        Next i
    End With
 
CreateWeekDaysTableBye:
    On Error Resume Next
    Set idx = Nothing
    Set tbl = Nothing
    rst.Close
    Set rst = Nothing
    Exit Sub
 
CreateWeekDaysTableErr:
    MsgBox "Произошла ошибка при выполнении процедуры " & _
    "[CreateWeekDaysTable] :" & vbCrLf & _
    Err.Description & vbCrLf & _
    "Номер ошибки = " & Err.Number, vbCritical
    Resume CreateWeekDaysTableBye
End Sub
 
'--------------------------------------------------------------------
 
Private Function DayName(DayNo As Integer) As String
'es 26.10.2000
'Вспомагательная = Возвращает название дня недели по его номеру
'--------------------------------------------------------------------
On Error GoTo DayNameErr
    Select Case DayNo
        Case 1: DayName = "Понедельник"
        Case 2: DayName = "Вторник"
        Case 3: DayName = "Среда"
        Case 4: DayName = "Четверг"
        Case 5: DayName = "Пятница"
        Case 6: DayName = "Суббота"
        Case 7: DayName = "Воскресенье"
    End Select
DayNameBye:     Exit Function
DayNameErr:     DayName = "#Error#": Resume DayNameBye
End Function
1
Особый статус
 Аватар для FloppyDisc
623 / 221 / 164
Регистрация: 18.11.2015
Сообщений: 1,086
11.12.2017, 10:25  [ТС]
Eugene-LS, и в правду, забыл что можно работать с объектами

Добавлено через 3 минуты
Но все же вопрос не совсем закрыт

Хотя позже переделаю в ООП-шку)
0
Эксперт MS Access
26826 / 14506 / 3192
Регистрация: 28.04.2012
Сообщений: 15,782
11.12.2017, 10:33
Лучший ответ Сообщение было отмечено FloppyDisc как решение

Решение

Цитата Сообщение от FloppyDisc Посмотреть сообщение
ограничение по длине
Для DECIMAL программно можно задать атрибуты, если пользоваться ADODB. В запросе в конструкторе не получится.
Visual Basic
1
currentproject.connection.execute "create table t (Десятичное decimal(15,3))
Что за тип TINYINT не знаю. Для INTEGER всегда 4 байта, Long 8 байтов. В 64-битном Access LongLong 16 байт. Для BINARY (OLE поле) ограничение в 1 ГБ, текстовое поле до 255 символов
Visual Basic
1
currentproject.connection.execute "create table t1 (Текст text(20))
1
Особый статус
 Аватар для FloppyDisc
623 / 221 / 164
Регистрация: 18.11.2015
Сообщений: 1,086
11.12.2017, 10:38  [ТС]
mobile,
Цитата Сообщение от mobile Посмотреть сообщение
Что за тип TINYINT не знаю
https://msdn.microsoft.com/en-... e.12).aspx надеюсь это SQLServer

Цитата Сообщение от mobile Посмотреть сообщение
Что за тип TINYINT не знаю. Для INTEGER всегда 4 байта, Long 8 байтов. В 64-битном Access LongLong 16 байт. Для BINARY (OLE поле) ограничение в 1 ГБ, текстовое поле до 255 символов
Т.е получается остается только так проверять:
Visual Basic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
' Если тип поля является строкой
        If CreateTable!U_C_Type = "STRING" Then
        
            ' И если у него пустое значение длины устанавливаем тип MEMO
            If IsNull(CreateTable!N_Length) Then
                f = "memo"
            ' Иначе TEXT(LEN)
            Else
                f = "text(" & CreateTable!N_Length & ")"
            End If
            
        ' Иначе же просто определяем наж тип
        ElseIf (CreateTable!U_C_Type = "INTEGER" Or CreateTable!U_C_Type = "TINYINT" Or CreateTable!U_C_Type = "SMALLINT") Then
            f = CreateTable!U_C_Type
        Else
            f = CreateTable!U_C_Type & "(" & CreateTable!N_Length & ")"
        End If
?

Кстати, это вы делали эту основу мне когда-то Если помните, тут вся конструкция собирается из таблицы с описанием
0
Эксперт MS Access
 Аватар для Eugene-LS
13172 / 5869 / 1504
Регистрация: 05.10.2016
Сообщений: 16,488
11.12.2017, 10:45
Цитата Сообщение от mobile Посмотреть сообщение
Что за тип TINYINT не знаю.
Насколько помню в переводе на язык MSA = dbInteger
1
Особый статус
 Аватар для FloppyDisc
623 / 221 / 164
Регистрация: 18.11.2015
Сообщений: 1,086
11.12.2017, 11:08  [ТС]
Eugene-LS, Спасибо вам большое за пример ООП вот накидал по вашему примеру:
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
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
Sub CreateDynamicObjectTableFromDescription(DescriptionTable As String, CreationTable As String)
 
Dim tbl As TableDef
Dim idx As Index
Dim fld As Field
Dim rst As Recordset
Dim i As Integer
Dim CreateTable As dao.Recordset
Dim ftype, flength, ifPrimary
 
On Error Resume Next
    CurrentDb.TableDefs.Delete CreationTable
    Err.Clear
    
On Error GoTo CreateTableErr
 
Set CreateTable = CurrentDb.OpenRecordset("SELECT *, UCase(C_Type) as U_C_Type FROM [" & DescriptionTable & "]")
Set tbl = CurrentDb.CreateTableDef(CreationTable)
 
' Проходимся по RecordSet-у циклом
  Do Until CreateTable.EOF
  
  ' Дефолтное значение сборщиков и замыкателей
    ftype = ""
    flength = 0
    ifPrimary = False
    
    ' Если поле имеет статус равное 1, то собираем его по частям
    If CreateTable!N_Status = 1 Then
    
        If CreateTable!U_C_Type = "STRING" Then
        
            If IsNull(CreateTable!N_Length) Then
                ftype = "memo"
                flength = 0
            Else
                ftype = "text"
                flength = CreateTable!N_Length
            End If
            
        ElseIf (CreateTable!U_C_Type = "INTEGER" Or CreateTable!U_C_Type = "TINYINT" Or CreateTable!U_C_Type = "SMALLINT") Then
            ftype = CreateTable!U_C_Type
            flength = 0
        Else
            ftype = CreateTable!U_C_Type
            flength = CreateTable!N_Length
        End If
        
        With tbl
            If flength > 0 Then
                .Fields.Append tbl.CreateField(CreateTable!C_Name, dbText, flength)
            Else
                .Fields.Append tbl.CreateField(CreateTable!C_Name, dbText)
            End If
 
            If (CreateTable!N_IsPrimary = 1 And ifPrimary = False) Then
                Set idx = .CreateIndex("Primary Key")
                    With idx
                        .Fields.Append .CreateField(CreateTable!C_Name)
                        .Unique = True
                        .Primary = True
                    End With
                .Indexes.Append idx
                ifPrimary = True
            End If
    End With
    
    End If
    
    CreateTable.MoveNext
  Loop
  
  CurrentDb.TableDefs.Append tbl
 
CreateTableBye:
    On Error Resume Next
    Set idx = Nothing
    Set tbl = Nothing
    rst.Close
    Set rst = Nothing
    Exit Sub
    
CreateTableErr:
    MsgBox "????????? ?????? ??? ?????????? ????????? " & _
    "[CreateTable] :" & vbCrLf & _
    Err.Description & vbCrLf & _
    "????? ?????? = " & Err.Number, vbCritical
    Resume CreateTableBye
End Sub
НО опять же проблема, теперь ведь мне придется определять тип данных
.Fields.Append tbl.CreateField(CreateTable!C_Name, dbText, flength), тут dbText мне не подходит, в таблице с описанием все находится в формате обычной инструкции CREATE TABLE, т.е TEXT, VARCHAR, CHRA, INTEGER.

Так вот, я конечно могу впихнуть много условий или Switch, но все же как сделать это красивее, МБ можно создать какой-то массив со всеми возможными типами и возвращать то нужное значение, если оно есть в этом массиве?

И еще вопрос, т.е тут получится вариант создания длин для полей типа INT, вроде сработало

Добавлено через 9 минут
Eugene-LS, mobile, Особенно порадовало то, что можно задавать значения по умолчанию прямо тут, иначе мне приходилось делать ALTER TABLE для каждого созданного поля
Visual Basic
1
.defaultValue = CreateTable!C_Default
Но как добавить атрибутты NULL/NOT NULL?
0
Эксперт MS Access
 Аватар для Eugene-LS
13172 / 5869 / 1504
Регистрация: 05.10.2016
Сообщений: 16,488
11.12.2017, 11:13
Цитата Сообщение от FloppyDisc Посмотреть сообщение
TEXT, VARCHAR, CHRA, INTEGER.
Тут нужно понимать что поля MSA не всегда сопоставимы с MySQL.
точнее вообще не сопоставимы.
Я , к сожалению, не совсем понимаю вашу задчку.
Кидайте через драйвер SQL запрос на создание - и должно отработать.
0
Особый статус
 Аватар для FloppyDisc
623 / 221 / 164
Регистрация: 18.11.2015
Сообщений: 1,086
11.12.2017, 11:21  [ТС]
Цитата Сообщение от Eugene-LS Посмотреть сообщение
Я , к сожалению, не совсем понимаю вашу задчку.
Хорошо, попробую объяснить. Нужно создать таблицу из имеющихся данных в таблице с описанием(Прикрепленный изоб.) вроде все работает, но хотелось бы подкорректировать некоторые элементы, особенно условия, я уже описывал проблему выше, вот что сделал сначала:
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
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
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
Sub CreateDynamicTableFromDescription(DescriptionTable As String, CreationTable As String)
  
  Dim db As dao.Database, CreateTable As dao.Recordset, AlterTable As dao.Recordset
  
  '  Объявляется главным сборщиком инструкции
  '  Объявляется началом инструкции
  '  Объявляется сборщиком полей (вместе с p & n)
  '  Объявляется хранителем ключевого поля PRIMARY KEY
  '  Объявляется сборщиком связки [NULL, NOT NULL]
  '  Объявляется главным сборщиком инструкции ALTER TABLE
  Dim CreateTableQuery, r, f, p, n, d, AlterSqlв
  
  ' Является замком замыкателем для хранителя p, закрывает возможность создания двух PRIMARY KEY в таблице
  Dim ifPrimary As Boolean
  
  ' Дефолтное значение ключ не был активирован 
  ifPrimary = False
  
  On Error GoTo isErr
  
  ' Устанавливаем соединение с текущей базой данных
  Set db = CurrentDb
  
  ' Открываем соединение и выполняем запрос на получение данных с описанием создаваемой таблицы, с верхним регистром Типа Поля
  Set CreateTable = db.OpenRecordset("SELECT *, UCase(C_Type) as U_C_Type FROM [" & DescriptionTable & "]")
  
  ' Начинаем сборку инструкции
  r = "CREATE TABLE [" & CreationTable & "] ("
  
  Do Until CreateTable.EOF
  
  ' Дефолтное значение сборщиков и замыкателей
    f = ""
    p = ""
    n = ""
    d = ""
    
    ' Если поле имеет статус равное 1, то собираем его по частям
    If CreateTable!N_Status = 1 Then
    
        ' Если тип поля является строкой
        If CreateTable!U_C_Type = "STRING" Then
        
            ' И если у него пустое значение длины устанавливаем тип MEMO
            If IsNull(CreateTable!N_Length) Then
                f = "memo"
            ' Иначе TEXT(LEN)
            Else
                f = "text(" & CreateTable!N_Length & ")"
            End If
            
        ' Иначе же просто определяем наж тип
        ElseIf (CreateTable!U_C_Type = "INTEGER" Or CreateTable!U_C_Type = "TINYINT" Or CreateTable!U_C_Type = "SMALLINT") Then
            f = CreateTable!U_C_Type
        Else
            f = CreateTable!U_C_Type & "(" & CreateTable!N_Length & ")"
        End If
    
        ' Если поле имеет статус ключа, то инициализируем его как PRIMARY KEY и замыкаем цикл ключей
        If (CreateTable!N_IsPrimary = 1 And ifPrimary = False) Then
            p = " PRIMARY KEY"
            ifPrimary = True
        Else
            p = ""
        End If
        
        ' Если поле имеет стутус NOT NULL, а так же он не является ключом
        If (CreateTable!N_IsNullable = 1 And CreateTable!N_IsPrimary <> 1) Then
            n = " NOT NULL"
        ' Если поле имеет статус NULL, а так же он не является ключом
        ElseIf (CreateTable!N_IsNullable = 2 And CreateTable!N_IsPrimary <> 1) Then
            n = " NULL"
        Else
            n = ""
        End If
        
        ' Собираем поле со всеми собранными атрибутами
        f = "[" & CreateTable!C_Name & "]" & " " & f & n & p
        
        ' Собираем текущую конструкцию с предыдущим а так же с собранным полем
        CreateTableQuery = CreateTableQuery & "," & f
    End If
    
    CreateTable.MoveNext
  Loop
  
  ' Сборка конечной конструкции
  CreateTableQuery = r & Mid(CreateTableQuery, 2) & ")"
  
  ' Посмотрим что получилось
  MsgBox CreateTableQuery
  
  ' Проверка на существоание создаваемой таблицы
  If ifTableExists(CreationTable) Then
  
  ' Проверка на ввод данных, чобы создаваемая таблица не являлась в тоже время и описанием
  If (CreationTable = "description") Then GoTo sysErr
  
  ' При существовании таблицы и ее открытость, если открыто закрываем, а так же удаляем таблицу
    If (SysCmd(acSysCmdGetObjectState, acTable, CreationTable) = 1) Then
       DoCmd.Close acTable, CreationTable
    End If
    db.Execute "DROP TABLE [" & CreationTable & "]"
  End If
  
  'Выполняем нашу инструкцию CREATE TABLE
  db.Execute CreateTableQuery
  
  'Debug.Print (CreateTableQuery)
  
  ' Начинаем модифицировать таблицу ALTER TABLE, открываем новый RecordSet
  Set AlterTable = db.OpenRecordset("SELECT * FROM [" & DescriptionTable & "]")
  
  Do Until AlterTable.EOF
    ' Проверяем, есть ли дефолтное значение, то что поле не является ключевым, то что не имеет значение NULL и то что имеет статус "СОЗДАТЬ"
    If (Len(AlterTable!C_Default) > 0 And AlterTable!N_IsPrimary <> 1 And AlterTable!N_IsNullable <> 2 And AlterTable!N_Status = 1) Then
        AlterSql = "ALTER TABLE [" & CreationTable & "] ALTER COLUMN [" & AlterTable!C_Name & "] SET DEFAULT " & AlterTable!C_Default & " ; "
    End If
    
    ' Проверяем наш сборщик на отличность от нуля или пустоты
    If Len(AlterSql) > 0 Then
        ' Смотрим каждый запрос
        MsgBox AlterSql
        
        ' Выполняем конструкцию ALTER TABLE
        CurrentProject.Connection.Execute AlterSql
    End If
    
    ' Обнуляем сборщик
    AlterSql = ""
    
    AlterTable.MoveNext
  Loop
 
' Обработчики ошибок
errNo:
  Exit Sub
isErr:
  MsgBox "Ошибка создания таблицы: " & Err & " " & Err.Description
sysErr:
  MsgBox "Вы пытаетесь удалить или перезаписать основную таблицу"
  Resume errNo
End Sub
 
Public Function ifTableExists(tblName As String) As Boolean
 
    If DCount("[Name]", "MSysObjects", "[Name] = '" & tblName & "'") = 1 Then
 
        ifTableExists = True
 
    End If
 
End Function
Миниатюры
Создание таблицы посредством VBA  
0
Особый статус
 Аватар для FloppyDisc
623 / 221 / 164
Регистрация: 18.11.2015
Сообщений: 1,086
11.12.2017, 11:23  [ТС]
Как видно из рисунка поле C_Type хранит строки типа String, Integer, а в объектной модели будет dbText, dbInteger, как красиво и правильно трансформировать все это?
вот эту часть:
Visual Basic
1
2
3
4
5
If flength > 0 Then
                .Fields.Append tbl.CreateField(CreateTable!C_Name, ТУТ_ОПРЕДЕЛЕННОЕ_ПОЛЕ, flength)
            Else
                .Fields.Append tbl.CreateField(CreateTable!C_Name, ТУТ_ОПРЕДЕЛЕННОЕ_ПОЛЕ_УЖЕ_БЕЗ_ДЛИНЫ)
            End If
И как эта часть будет выглядеть в объектной модели:
Visual Basic
1
2
3
4
5
6
7
8
9
' Если поле имеет стутус NOT NULL, а так же он не является ключом
        If (CreateTable!N_IsNullable = 1 And CreateTable!N_IsPrimary <> 1) Then
            n = " NOT NULL"
        ' Если поле имеет статус NULL, а так же он не является ключом
        ElseIf (CreateTable!N_IsNullable = 2 And CreateTable!N_IsPrimary <> 1) Then
            n = " NULL"
        Else
            n = ""
        End If
0
Эксперт MS Access
 Аватар для Eugene-LS
13172 / 5869 / 1504
Регистрация: 05.10.2016
Сообщений: 16,488
11.12.2017, 11:26
Цитата Сообщение от FloppyDisc Посмотреть сообщение
Нужно создать таблицу из имеющихся данных в таблице
Создать таблицу ГДЕ?
На сервере MySQL - или в БД MSA?
0
Особый статус
 Аватар для FloppyDisc
623 / 221 / 164
Регистрация: 18.11.2015
Сообщений: 1,086
11.12.2017, 11:29  [ТС]
Цитата Сообщение от Eugene-LS Посмотреть сообщение
На сервере MySQL - или в БД MSA?
В MSA, я думал это понятно, извиняюсь

Наверное вас смутили сссылки на MySQL )) и типы данных VARCHAR, INTEGER...
0
Эксперт MS Access
 Аватар для Eugene-LS
13172 / 5869 / 1504
Регистрация: 05.10.2016
Сообщений: 16,488
11.12.2017, 11:38
FloppyDisc, если в MSA - то аналогично примеру.
Задаём свойства и параметры полей через DAO.
Всё стандартно.

Добавлено через 1 минуту
FloppyDisc, если структура заранее известна - я использую шаблоны.
0
Особый статус
 Аватар для FloppyDisc
623 / 221 / 164
Регистрация: 18.11.2015
Сообщений: 1,086
11.12.2017, 11:56  [ТС]
Цитата Сообщение от Eugene-LS Посмотреть сообщение
Задаём свойства и параметры полей через DAO.
Всё стандартно.
Я очень плохо разбираюсь в VBA, поэтому и спрашиваю, как задать значение по умолчанию и атрибуты NULL/NOT NULL, какие это методы?)

Добавлено через 5 минут
Цитата Сообщение от Eugene-LS Посмотреть сообщение
я использую шаблоны.
Что это за шаблоны?

Добавлено через 7 минут
Вот в чем проблема:
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
30
31
32
33
34
Select Case CreateTable!U_C_Type
            Case "STRING", "CHAR", "VARCAHR", "TEXT"
                If IsNull(CreateTable!N_Length) Then
                    ftype = dbMemo
                    flength = 0
                Else
                    ftype = dbText
                    flength = CreateTable!N_Length
                End If
            Case "INTEGER", "TINYINT", "SMALLINT"
                ftype = dbInteger
                flength = 0
            Case "LONG"
                ftype = dbLong
                flength = 0
            Case "DOUBLE"
                ftype = dbDouble
                flength = 0
            Case "DATETIME"
                ftype = dbDate
                flength = 0
            Case "CURRENCY"
                ftype = dbCurrency
                flength = 0
            Case Else
                ftype = dbText
        End Select
...
 
If flength > 0 Then
                .Fields.Append tbl.CreateField(CreateTable!C_Name, ftype, flength)
            Else
                .Fields.Append tbl.CreateField(CreateTable!C_Name, ftype)
            End If
Не понимаю фишек VBA, как можно укоротить и облегчить код
0
Эксперт MS Access
 Аватар для Eugene-LS
13172 / 5869 / 1504
Регистрация: 05.10.2016
Сообщений: 16,488
11.12.2017, 11:58
Цитата Сообщение от FloppyDisc Посмотреть сообщение
Я очень плохо разбираюсь в VBA, поэтому и спрашиваю, как задать значение по умолчанию и атрибуты NULL/NOT NULL, какие это методы?
Понял.
Это свойства объекта Field из коллекции Fields где парентом Table
Помните?
Visual Basic
1
2
3
4
    With tbl
        .Fields.Append tbl.CreateField("DayID", dbLong)
        .Fields.Append tbl.CreateField("DayName", dbText, 20)
        ...
Это простой вариант.
На самом деле, перед добавлением, вы можете обозначить всё множество свойств добавляемого поля.
Но я так пока не пробовал, но согласно объектной модели должно отработать.
т.е. вы поступаете с об]ектом Field так - же как и с индексом в примере, задавая свойства перед добавлением.

Надеюсь был понятен ...
0
Модератор
Эксперт MS Access
6231 / 2909 / 707
Регистрация: 12.06.2016
Сообщений: 7,839
11.12.2017, 12:05
Цитата Сообщение от FloppyDisc Посмотреть сообщение
как задать значение по умолчанию и атрибуты NULL/NOT NULL
Visual Basic
1
2
CurrentDb.TableDefs("имя таблицы").Fields("имя поля").Properties("DefaultValue") = "значение"
CurrentDb.TableDefs("имя таблицы").Fields("имя поля").Properties("AllowZeroLength") = True/False
1
Особый статус
 Аватар для FloppyDisc
623 / 221 / 164
Регистрация: 18.11.2015
Сообщений: 1,086
11.12.2017, 12: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
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
Sub CreateDynamicObjectTableFromDescription(DescriptionTable As String, CreationTable As String)
 
Dim tbl As TableDef
Dim idx As Index
Dim fld As Field
Dim rst As Recordset
Dim CreateTable As dao.Recordset
Dim ftype, flength, ifPrimary
 
On Error Resume Next
    CurrentDb.TableDefs.Delete CreationTable
    Err.Clear
    
On Error GoTo CreateTableErr
 
Set CreateTable = CurrentDb.OpenRecordset("SELECT *, UCase(C_Type) as U_C_Type FROM [" & DescriptionTable & "]")
Set tbl = CurrentDb.CreateTableDef(CreationTable)
 
' Ïðîõîäèìñÿ ïî RecordSet-ó öèêëîì
  Do Until CreateTable.EOF
  
  ' Äåôîëòíîå çíà÷åíèå ñáîðùèêîâ è çàìûêàòåëåé
    ftype = ""
    flength = 0
    ifPrimary = False
    
    ' Åñëè ïîëå èìååò ñòàòóñ ðàâíîå 1, òî ñîáèðàåì åãî ïî ÷àñòÿì
    If CreateTable!N_Status = 1 Then
    
        Select Case CreateTable!U_C_Type
            Case "STRING", "CHAR", "VARCAHR", "TEXT"
                If IsNull(CreateTable!N_Length) Then
                    ftype = dbMemo
                    flength = 0
                Else
                    ftype = dbText
                    flength = CreateTable!N_Length
                End If
            Case "INTEGER", "TINYINT", "SMALLINT"
                ftype = dbInteger
                flength = 0
            Case "LONG"
                ftype = dbLong
                flength = 0
            Case "DOUBLE"
                ftype = dbDouble
                flength = 0
            Case "DATETIME"
                ftype = dbDate
                flength = 0
            Case "CURRENCY"
                ftype = dbCurrency
                flength = 0
            Case Else
                ftype = dbText
        End Select
 
        
        
        With tbl
            If flength > 0 Then
                .Fields.Append tbl.CreateField(CreateTable!C_Name, ftype, flength)
            Else
                .Fields.Append tbl.CreateField(CreateTable!C_Name, ftype)
            End If
 
            If (CreateTable!N_IsPrimary = 1 And ifPrimary = False) Then
                Set idx = .CreateIndex("Primary Key")
                    With idx
                        .Fields.Append .CreateField(CreateTable!C_Name)
                        .Unique = True
                        .Primary = True
                    End With
                .Indexes.Append idx
                ifPrimary = True
            End If
            
            If (Len(CreateTable!C_Default) > 0 And CreateTable!N_IsPrimary <> 1 And CreateTable!N_IsNullable <> 2 And CreateTable!N_Status = 1) Then
                .Fields(CreateTable!C_Name).defaultValue = CreateTable!C_Default
            End If
    End With
    
    End If
    
    CreateTable.MoveNext
  Loop
  
  CurrentDb.TableDefs.Append tbl
 
CreateTableBye:
    On Error Resume Next
    Set idx = Nothing
    Set tbl = Nothing
    rst.Close
    Set rst = Nothing
    Exit Sub
    
CreateTableErr:
    MsgBox "????????? ?????? ??? ?????????? ????????? " & _
    "[CreateTable] :" & vbCrLf & _
    Err.Description & vbCrLf & _
    "????? ?????? = " & Err.Number, vbCritical
    Resume CreateTableBye
End Sub

Цитата Сообщение от Eugene-LS Посмотреть сообщение
На самом деле, перед добавлением, вы можете обозначить всё множество свойств добавляемого поля.
да, именно, но я даже не знаю какие методы есть, в гугле искал не могу найти для NULL/NOT NULL , CONSTAIN

А второе, очень раздражает конструкция типа:
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
Select Case CreateTable!U_C_Type
            Case "STRING", "CHAR", "VARCAHR", "TEXT"
                If IsNull(CreateTable!N_Length) Then
                    ftype = dbMemo
                    flength = 0
                Else
                    ftype = dbText
                    flength = CreateTable!N_Length
                End If
            Case "INTEGER", "TINYINT", "SMALLINT"
                ftype = dbInteger
                flength = 0
            Case "LONG"
                ftype = dbLong
                flength = 0
            Case "DOUBLE"
                ftype = dbDouble
                flength = 0
            Case "DATETIME"
                ftype = dbDate
                flength = 0
            Case "CURRENCY"
                ftype = dbCurrency
                flength = 0
            Case Else
                ftype = dbText
        End Select
Как ее пофиксить нормально?

Добавлено через 1 минуту
Capi,
Visual Basic
1
CurrentDb.TableDefs("имя таблицы").Fields("имя поля").Properties("AllowZeroLength") = True/False
круто, спасибо, для дефолта я уже сделал)

Добавлено через 3 минуты
Capi, а что есть true и false который NULL?
Visual Basic
1
.Fields(CreateTable!C_Name).AllowZeroLength = True / False
0
Модератор
Эксперт MS Access
6231 / 2909 / 707
Регистрация: 12.06.2016
Сообщений: 7,839
11.12.2017, 12:23
Цитата Сообщение от FloppyDisc Посмотреть сообщение
а что есть true и false который NULL?
Да вроде очевидно же...
Да/Нет (Можно/Нельзя)....
True (-1) A zero-length string is a valid entry.
False (0) (Default) A zero-length string is an invalid entry.

Есть еще свойство Required - обязательное/необязательное поле (для числовых).
А AllowZeroLength - для текстовых, возможность пустой строки.
Для NULL это скорее Required нужно.
1
Особый статус
 Аватар для FloppyDisc
623 / 221 / 164
Регистрация: 18.11.2015
Сообщений: 1,086
11.12.2017, 12:31  [ТС]
Capi, просто NULL срабатывает, а NOT NULL - нет, я бы не стал спрашивать, если бы не было бы непонятки

Добавлено через 5 минут
Capi,
Цитата Сообщение от Capi Посмотреть сообщение
Для NULL это скорее Required нужно.
Да, это сработало!
0
Модератор
Эксперт MS Access
6231 / 2909 / 707
Регистрация: 12.06.2016
Сообщений: 7,839
11.12.2017, 12:31
Цитата Сообщение от FloppyDisc Посмотреть сообщение
просто NULL срабатывает, а NOT NULL - нет
Visual Basic
1
CurrentDb.TableDefs("имя таблицы").Fields("имя поля").Properties("Required") = True/False
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
11.12.2017, 12:31
Помогаю со студенческими работами здесь

Об экспорте данных посредством VBA
Помогите, плз, разобраться в таком вопросе. Передо мной стоит задача экспорта данных в текстовый файл с полями фиксированной ширины. Как...

Изменение поля посредством VBA
Такая проблема. Нужно при нажатии на форме кнопки изменить данные в таблице. Из таблицы компьютеры принимается заявка на ремонт....

Скрытие, отображение вкладки посредством VBA
Доброго времени суток! Не могу понять, что происходит с наборомВкладок в разделенной форме: Хочу сделать чтобы при переходе по записям,...

Блокировка записи через VBA посредством ADODB
Здравствуйте. Всё в базе работает через VBA (Select, Update, формы и т.д.). Решил проверку записи на изменение сделать через блокировку...

Автоматическая обработка записей при загрузке формы посредством VBA
Здравствуйте! Есть форма, данные из таблицы. В ней есть порядковый номер особи и номер вида животного (подсталяется из другой...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
Управление камерой с помощью скрипта OrbitControls.js на Three.js: Вращение, зум и панорамирование
8Observer8 05.03.2026
Содержание блога Финальная демка в браузере работает на Desktop и мобильных браузерах. Итоговый код: orbit-controls-threejs-js. zip. На мобильном - сканируйте QR-код. Вращайте камеру одним пальцем,. . .
SDL3 для Web (WebAssembly): Синхронизация спрайтов SDL3 и тел Box2D
8Observer8 04.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-sync-physics-sprites-sdl3-c. zip На первой гифке отладочные линии отключены, а на второй включены:. . .
SDL3 для Web (WebAssembly): Идентификация объектов на Box2D v3 - использование userData и событий коллизий
8Observer8 02.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-collision-events-sdl3-c. zip Сканируйте QR-код на мобильном и вы увидите, что появится джойстик для управления главным героем. . . .
Реалии
Hrethgir 01.03.2026
Нет, я не закончил до сих пор симулятор. Эта задача сложнее. Не получилось уйти в плавсостав, но оно и к лучшему, возможно. Точнее получалось - но сварщиком в палубную команду, а это значит, в моём. . .
Ритм жизни
kumehtar 27.02.2026
Иногда приходится жить в ритме, где дел становится всё больше, а вовлечения в происходящее — всё меньше. Плотный график не даёт вниманию закрепиться ни на одном событии. Утро начинается с быстрых,. . .
SDL3 для Web (WebAssembly): Сборка библиотек: SDL3, Box2D, FreeType, SDL3_ttf, SDL3_mixer и SDL3_image из исходников с помощью CMake и Emscripten
8Observer8 27.02.2026
Недавно вышла версия 3. 4. 2 библиотеки SDL3. На странице официальной релиза доступны исходники, готовые DLL (для x86, x64, arm64), а также библиотеки для разработки под Android, MinGW и Visual Studio. . . .
SDL3 для Web (WebAssembly): Реализация движения на Box2D v3 - трение и коллизии с повёрнутыми стенами
8Observer8 20.02.2026
Содержание блога Box2D позволяет легко создать главного героя, который не проходит сквозь стены и перемещается с заданным трением о препятствия, которые можно располагать под углом, как верхнее. . .
Конвертировать закладки radiotray-ng в m3u-плейлист
damix 19.02.2026
Это можно сделать скриптом для PowerShell. Использование . \СonvertRadiotrayToM3U. ps1 <path_to_bookmarks. json> Рядом с файлом bookmarks. json появится файл bookmarks. m3u с результатом. # Check if. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru