Сгенерируйте УНИКАЛЬНУЮ строку, состоящую из цифр / АЛФАВИТ

Моя проблема

  • Я не знаю никакого VBA
  • Необходимо сгенерировать строку из 12 символов (ALPHA + числа, 0-9, A-Z) IN VBA...
  • Пример вывода:

    "ADF3V3224K1WQ"
    

    (12 символов в длину, заглавные буквы алфавита и числовые значения).


История

Мне трудно понять, как создать генератор строк (не сказал, что он должен быть случайным, но он должен быть уникальным на 100%, то есть он должен проверять наличие дубликатов или сохранять существующие значения), у меня есть без опыта работы с VBA. Я уже нашел подобный пост здесь, но он отличается от моего, так как специально не требует, чтобы строка была уникальной на 100%. (Мне не нужен очень низкий шанс, мне нужен 100% по всем направлениям).

Что касается синтаксиса, я довольно запутался, мне удалось найти, где находится код событий, т.е. нажатия кнопок, поэтому я знаю, где мне нужно его написать, но я понятия не имею, как проверить дублирование. (даже полагаться на семя времени, которое может гарантировать, что оно будет на 100% уникальным, здорово).

Ссылка на аналогичную запись: MS Access Visual Basic — генерировать случайную строку в текстовом поле


person Yuval    schedule 05.07.2017    source источник
comment
101 % уникальности. Начните с вопроса: где хранятся уже использованные ранее сгенерированные строки? Как? Скорее всего, нам не нужно хранить их все, но, по крайней мере, нам нужно где-то держать счетчик.   -  person A.S.H    schedule 05.07.2017
comment
Дело в том, что мои знания о доступе к офису (а офис в целом близок к нулю), дикая догадка (и я действительно имею в виду дикую), вероятно, находится в реальной таблице.   -  person Yuval    schedule 05.07.2017
comment
Если мы сможем узнать, в какой таблице хранятся эти значения. Тогда эта проблема станет намного проще.   -  person JahKnows    schedule 05.07.2017
comment
Боюсь, это на иврите, но я знаю таблицу. поле является первичным ключом. на него можно ссылаться как на operatorID (эквивалентно ивриту), а на таблицу tblOperator   -  person Yuval    schedule 05.07.2017
comment
Пожалуйста, прочитайте При каких обстоятельствах я могу добавить «срочно» или другие подобные фразы к моему вопросу, чтобы получить более быстрые ответы? - Подводя итог, можно сказать, что это не идеальный способ обращения к волонтерам и, вероятно, контрпродуктивно для получения ответов. Пожалуйста, воздержитесь от добавления этого к своим вопросам.   -  person halfer    schedule 07.07.2017


Ответы (3)


Ну, я думаю, если он действительно должен быть буквенно-цифровым и уникальным, это путь:

Этот код генерирует случайную строку символов на основе текущего времени (например, ответ @paul-bica), только он кодирует их буквенно-цифровым образом и использует таймер, чтобы получить доли секунды для достижения 12 символов). Таким образом, вы сможете генерировать несколько случайных строк в секунду.

Просто вызовите UniqueTimeBasedString(), чтобы получить строку. (Обратите внимание, что если вы используете эту функцию в запросе, Access кэширует результат, и он вообще не будет уникальным).

Public Function UniqueTimeBasedString() As String
    Dim alphanumericCharacters As String
    alphanumericCharacters = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
    Dim timeString As String
    timeString = Format(Now, "yymmddhhmmss") & Getmtimestring(6)
    Dim c As Integer
    Dim intTimepart As Integer
    c = 1
    Do While c < Len(timeString)
        intTimepart = CInt(Mid(timeString, c, 3))
        c = c + 3
        UniqueTimeBasedString = UniqueTimeBasedString & Mid(alphanumericCharacters, Int(intTimepart / 61) + 1, 1) & Mid(alphanumericCharacters, intTimepart Mod 61 + 1, 1)
    Loop
End Function

Public Function Getmtimestring(length As Integer) As String
    Dim mtime As Double
    mtime = Timer()
    Dim mtimeLng As Long
    mtimeLng = Int((mtime - Int(mtime)) * (10 ^ length))
    Getmtimestring = CStr(mtimeLng)
    Do While Len(Getmtimestring) < length
        Getmtimestring = "0" & Getmtimestring
    Loop
End Function

Примечания:

  1. Timer() не совсем точен, и теоретически это может вызвать проблемы
  2. Этот код несовместим с OS X, но это не будет проблемой, если вы останетесь ограниченным доступом (Getmtimestring просто вернет нули)
  3. Вам действительно стоит поговорить с вашим боссом. Просить вас сделать что-то, для чего вы на самом деле не подходите, со сжатыми сроками и без возможности использовать немного другое решение — нездоровое поведение на рабочем месте.
  4. Строка содержит закодированное время и может быть декодировано. Не сообщайте об этом, если хотите, чтобы время создания строки было секретным.
person Erik A    schedule 06.07.2017

Есть несколько решений этой проблемы, но мне нравится это:

Public Function newguidx() As String
    With CreateObject("Scriptlet.TypeLib")
        newguidx = Left(.Guid, 38)
    End With  
End Function

Он создает GUID. Они не уникальны сами по себе, но вы можете прочитать на странице Википедии, что они вполне могут быть таковыми. Вы можете использовать Replace, чтобы удалить знаки {}-, если хотите.

Кроме того, поскольку формат стандартизирован, большинству программистов будет понятно, что это такое.

Очевидно, вы можете обрезать символы, чтобы получить желаемую длину, и это увеличит ваши шансы найти дубликат.

Редактировать:

К сожалению, доступ к Scriptlet.TypeLib в настоящее время заблокирован по умолчанию из соображений безопасности. См. Ошибка MS Access VBA: ошибка времени выполнения "70" Отказано в доступе для получения информации об этом и Как я могу генерировать идентификаторы GUID в Excel? для хорошего обзора нескольких методов создания GUID.

Мои личные предпочтения:

Public Function CreateGUID() As String
    Do While Len(CreateGUID) < 32
        If Len(CreateGUID) = 16 Then
            '17th character holds version information
            CreateGUID = CreateGUID & Hex$(8 + CInt(Rnd * 3))
        End If
        CreateGUID = CreateGUID & Hex$(CInt(Rnd * 15))
    Loop
    CreateGUID = "{" & Mid(CreateGUID, 1, 8) & "-" & Mid(CreateGUID, 9, 4) & "-" & Mid(CreateGUID, 13, 4) & "-" & Mid(CreateGUID, 17, 4) & "-" & Mid(CreateGUID, 21, 12) & "}"
End Function
person Erik A    schedule 06.07.2017
comment
Нет, но это обычно используется для идентификации уникальных случаев, и, как утверждает Википедия: Таким образом, чтобы вероятность дублирования была один к миллиарду, необходимо сгенерировать 103 триллиона UUID версии 4. Я не знаю, насколько велика ваша база данных, но я думаю, что этого достаточно. - person Erik A; 06.07.2017
comment
Что, если длина строки будет 12 (мне нужно, чтобы она была не длиннее двенадцати). есть ли способ сказать, чтобы он снова запускался в случае обнаружения ошибки дублирования? скажем, ловить ошибки дублирования или (делать пока) duplication_error ‹› 0 (я не знаю синтаксис vba). - person Yuval; 06.07.2017
comment
Что ж, это ограничивает уникальность, увеличивая вероятность коллизий. Если у меня будет шанс, я поищу более подходящий ответ. Обратите внимание, что истинная уникальность невозможна, если только она не основана на времени (ограничивая вас максимальным 1 идентификатором в секунду или вызовами внешней библиотеки для получения микросекунд), или вам нужно будет вести журнал (начальное число) ранее созданные ответы. - person Erik A; 06.07.2017

Используйте строку даты и времени:

  • Формула: =TEXT(NOW(),"yymmddhhmmss") -> 170705161201

  • VBA: Debug.Print Format(Now, "yymmddhhmmss")

person paul bica    schedule 05.07.2017
comment
Пол, мне нравится твое решение, очень креативное, я, конечно, не думал об этом, но в нем нет символов от А до Я. - person Yuval; 05.07.2017
comment
Зачем заботиться? Вы можете генерировать уникальный номер каждую секунду в течение ста лет. - person Gustav; 06.07.2017
comment
Знаете ли вы, как я могу использовать его для автоматической генерации поля? Чтобы мне не нужно было нажимать кнопку или активировать событие, а оно автоматически активировалось при открытии новой записи? - person Yuval; 06.07.2017