По совету комментария. Теперь я могу решить ошибку.
Dim c As Integer = DataGridView1.SelectedRows.Count() - 1
For i As Integer = 0 To c
Dim deleteQuery As String = "DELETE from TBwarranty WHERE warranty='" & DataGridView1.SelectedRows(i).Cells(0).Value & "'"
Console.WriteLine(deleteQuery)
Try
T.ExecuteQuery(deleteQuery, connection)
Catch ex As System.Data.OleDb.OleDbException
MsgBox(ex.Message)
MessageBox.Show("Failed inserted.")
End Try
Next
UpdateGrid()
Один классик должен представить значение "неизвестного" типа, как в ядре упрощенной виртуальной машины:
typedef enum { INTEGER, STRING, REAL, POINTER } Type;
typedef struct
{
Type type;
union {
int integer;
char *string;
float real;
void *pointer;
} x;
} Value;
Используя это можно написать код, который обрабатывает "значения", не зная их точный тип, например, реализуйте стек и так далее.
Так как это находится в (старо, pre-C11) C, внутреннему объединению нужно дать имя поля во внешнем struct
. В C++ можно позволить union
будьте анонимными. Выбор этого имени может быть трудным. Я склонен идти с чем-то одно-буквой, так как на нее почти никогда не ссылаются в изоляции, и таким образом всегда ясно из контекста, что продолжается.
Код для устанавливания значения к целому числу мог бы быть похожим на это:
Value value_new_integer(int v)
{
Value v;
v.type = INTEGER;
v.x.integer = v;
return v;
}
Здесь я использую факт это struct
s можно возвратить непосредственно и рассматривать почти как значения типа примитива (можно присвоиться struct
s).
Объединения являются также наиболее часто используемыми на этапе лексического анализа и парсинга языковых процессоров, как компиляторы и интерпретаторы. Вот тот, который я редактирую прямо сейчас.
union {
char c;
int i;
string *s;
double d;
Expression *e;
ExpressionList *el;
fpos_t fp;
}
Объединение используется для соединения семантических значений с маркерами лексического анализатора и производством синтаксического анализатора. Эта практика является довольно обычной в генераторах грамматики, как yacc, который оказывает явную поддержку для нее. Объединение может содержать любое из своих значений, но только одного из них в то время. Например, в любой точке из входного файла Вы или считали символьную константу (сохраненный в c
), или целое число (сохраненный в i
) или число с плавающей точкой (сохраненный в d
). Генератор грамматики оказывает значительную помощь для определения, которое из значений хранится в любой момент в зависимости от обрабатываемого правила.
Вот немного один, я использую каждый день:
struct tagVARIANT {
union {
struct __tagVARIANT {
VARTYPE vt;
WORD wReserved1;
WORD wReserved2;
WORD wReserved3;
union {
LONG lVal; /* VT_I4 */
BYTE bVal; /* VT_UI1 */
SHORT iVal; /* VT_I2 */
FLOAT fltVal; /* VT_R4 */
DOUBLE dblVal; /* VT_R8 */
VARIANT_BOOL boolVal; /* VT_BOOL */
_VARIANT_BOOL bool; /* (obsolete) */
SCODE scode; /* VT_ERROR */
CY cyVal; /* VT_CY */
DATE date; /* VT_DATE */
BSTR bstrVal; /* VT_BSTR */
IUnknown * punkVal; /* VT_UNKNOWN */
IDispatch * pdispVal; /* VT_DISPATCH */
SAFEARRAY * parray; /* VT_ARRAY */
BYTE * pbVal; /* VT_BYREF|VT_UI1 */
SHORT * piVal; /* VT_BYREF|VT_I2 */
LONG * plVal; /* VT_BYREF|VT_I4 */
FLOAT * pfltVal; /* VT_BYREF|VT_R4 */
DOUBLE * pdblVal; /* VT_BYREF|VT_R8 */
VARIANT_BOOL *pboolVal; /* VT_BYREF|VT_BOOL */
SCODE * pscode; /* VT_BYREF|VT_ERROR */
CY * pcyVal; /* VT_BYREF|VT_CY */
DATE * pdate; /* VT_BYREF|VT_DATE */
BSTR * pbstrVal; /* VT_BYREF|VT_BSTR */
IUnknown ** ppunkVal; /* VT_BYREF|VT_UNKNOWN */
IDispatch ** ppdispVal; /* VT_BYREF|VT_DISPATCH */
SAFEARRAY ** pparray; /* VT_BYREF|VT_ARRAY */
VARIANT * pvarVal; /* VT_BYREF|VT_VARIANT */
PVOID byref; /* Generic ByRef */
CHAR cVal; /* VT_I1 */
USHORT uiVal; /* VT_UI2 */
ULONG ulVal; /* VT_UI4 */
INT intVal; /* VT_INT */
UINT uintVal; /* VT_UINT */
DECIMAL * pdecVal; /* VT_BYREF|VT_DECIMAL */
CHAR * pcVal; /* VT_BYREF|VT_I1 */
USHORT * puiVal; /* VT_BYREF|VT_UI2 */
ULONG * pulVal; /* VT_BYREF|VT_UI4 */
INT * pintVal; /* VT_BYREF|VT_INT */
UINT * puintVal; /* VT_BYREF|VT_UINT */
} __VARIANT_NAME_3;
} __VARIANT_NAME_2;
DECIMAL decVal;
} __VARIANT_NAME_1;
};
Это - определение типа данных варианта автоматизации OLE. Поскольку Вы видите, что это имеет много возможных типов. Существует много правил вокруг типов, которые можно использовать в различных ситуациях, в зависимости от поддержки намеченного клиентского кода. Не все типы поддерживаются всеми языками.
Типы с VT_BYREF
после них используются языками, такими как VBScript, которые передают параметры ссылкой по умолчанию. Это означает, есть ли у Вас некоторый код, который заботится о различных деталях структуры (таких как C++) о быть названным кодом, который не делает (такие как VB), затем необходимо тщательно разыменовать различный параметр при необходимости.
Типы byref также используются для возвращения значения от функций. Существует также поддержка типов массива с помощью неверно названного удачливого SAFEARRAY
введите - настолько трудный использовать от C++.
Если у Вас есть массив строк, можно передать его vbscript, но он не может использоваться (кроме распечатать размер). Для фактического чтения значений данные массива должны иметь тип VT_BYREF | VT_BSTR
.
Избегайте "взломов" с объединением, они вызывают головные боли мобильности (порядок байтов, проблемы выравнивания).
Законное использование объединения должно сохранить различные типы данных в том же месте, предпочтительно с тегом так, чтобы Вы знали, какой тип это. Посмотрите пример к 1800 ИНФОРМАЦИЯ.
Не используйте объединение для преобразования между типами данных, например, от целого числа до нескольких байтов. Используйте сдвиг и маскирующий вместо этого для мобильности.
Мы используем объединения для упакованных сообщений на работе (C/C++), таким образом, мы можем раздать структуру с объединением как элемент данных, затем получите доступ к корректному пути на основе идентификационного поля в структуре.
Хорошо работавший, пока кто-то не записал структуру в файл, теперь мы ограничены самыми большими данными, используемыми в файле, потому что даже при том, что существует версия файла, никто никогда не изменял его....
Таким образом, в то время как полезный для работы в оперативной памяти, постарайтесь не вслепую писать им в диск или сеть.
struct InputEvent
{
enum EventType
{
EventKeyPressed,
EventKeyPressRepeated,
EventKeyReleased,
EventMousePressed,
EventMouseMoved,
EventMouseReleased
} Type;
union
{
unsigned int KeyCode;
struct
{
int x;
int y;
unsigned int ButtonCode;
};
};
};
...
std::vector<InputEvent> InputQueue;
со взломом объединения я могу просто сделать вектор объектов. Я уверен, что это могло быть сделано более чистым..., но это работает на меня - KISS
По совпадению я просто использовал один в ответе Stackoverflow здесь, таким образом, я мог рассматривать слово, которое было составлено из 6 битовых полей как два целых числа без знака на 16 битов.
Несколько лет назад, я также использовал один для (первое) компилятор C ARM - инструкции в те дни составляли все 32 бита, но имели различные разметки в зависимости от точной инструкции. Таким образом, у меня было объединение для представления инструкции ARM, содержа ряд структур, которые у каждого были соответствующие битовые поля для типа конкретной инструкции.
#define DWORD unsigned int
#define WORD unsigned short
#define BYTE unsigned char
typedef union _DWORD_PART_ {
DWORD dwWord;
struct {
WORD dwMSB;
WORD dwLSB;
}hw;
struct {
BYTE byMSB;
BYTE byMSBL;
BYTE byLSBH;
BYTE byLSB;
} b;
} DWORD_PART;
Это - простой способ получить доступ к частям слов. (После того как Вы сделаны, любое изменение в порядке байтов платформы может также быть обработано легко),