Как сделать, чтобы в ячейке формировался уникальный идентификатор для каждой строки (записи)? Состав id не принципиален: цифры или текст, или случайный набор символов...
Как сделать, чтобы уникальный идентификатор для каждой строки (записи) не изменялся при удалении или добавлении записей?
Доброе время суток На событие Worksheet.Change в пределах таблицы добавляете проверку на пустое значение по столбцу id. Если пустое, то получаете guid для ввода в эту ячейку
Самое простое это прописать id при помощи любой формулы, но в этом случае оно изменится при изменении самой записи, бороться с этим можно при помощи макроса, который бы записывал id, как текст. Ну либо сделать простую формулу, результат которой не зависит от записи (2 вариант)
Function IDNum()
Static idn As Double
IDNum = Fix(Now * 10000000000#)
If idn < IDNum Then
idn = IDNum
Else
idn = idn + 1
IDNum = idn
End If
End Function
Sub Пример()
Cells(1, 1) = IDNum
'Можно потом использовать так
Cells(1, 2) = CDate(Cells(1, 1) / 10000000000#)
End Sub
AAF, тут есть подвох получить не уникальные значения если обработку делать пакетом. При разовом или с таймаутом применении - ОК. Однако, подобное я использовал в сочетании с данным одного из полей. Хотя вариант c GUID , раз уж лезем в VBA мне более нравится.
Я слабо разбираюсь в VBA. То, что вы написали в сообщении #4, воткнул в модуль... и всё.. Буду признателен, если скорректируете мой файл согласно предложенного вами решения..
Private Sub Worksheet_Change(ByVal Target As Range)
Dim cell
Dim ShNm As String 'имя листа
Dim Rng As Range 'та ячейка, где написано "ID"
ShNm = Me.Name
Set Rng = Sheets(ShNm).Cells(1, 1)
Set Rng = Rng.CurrentRegion.Resize(Rng.CurrentRegion.Rows.Count, 1)
For Each cell In Rng
If cell = "" Then cell.Value = IDNum
Next
End Sub
А функцию в простой модуль:
Код
Function IDNum()
Static idn As Double
IDNum = Fix(Now * 10000000000#)
If idn < IDNum Then
idn = IDNum
Else
idn = idn + 1
IDNum = idn
End If
End Function
файлик называется так: уник идент id_00 (1).XLSM Да? Заполнение происходит, когда производяться изменения на листе Может Вы забыли нажать кнопку "ВЛЮЧИТЬ СОДЕРЖИМОЕ"?
excel_pl, да, имелось ввиду, что id предполагает первый столбец региона (таблицы) Теперь будет именно тот столбец "C", в котором находится cells(r,C)
Код
Private Sub Worksheet_Change(ByVal Target As Range)
Dim cell, col
Dim ShNm As String 'имя листа
Dim Rng As Range 'ячейка, где написано "ID"
ShNm = Me.Name
Set Rng = Sheets(ShNm).Cells(1, 1)
col = Rng.Column 'запоминаем столбец
Set Rng = Rng.CurrentRegion 'определяем регион непрерывной таблицы
If Rng.Rows.Count = 1 Then Exit Sub 'если в регионе одна строка, а это заголовок, то данных нет, все бросаем и уходим
Set Rng = Rng.Resize(Rng.Rows.Count - 1, 1).Offset(1, col - Rng.CurrentRegion.Column) 'подгоняем размер под столбец обработки ID
Application.EnableEvents = False 'отключаем события, особенно Worksheet_Change, на время вставки нового ID
For Each cell In Rng 'перечисляем все ячейки входящие в Rng
If cell = "" Then cell.Value = IDNum 'если пустая, то втыкаем туда ID
Next
Application.EnableEvents = True 'не забываем включить события Worksheet_Change
End Sub
Дополню немного изменённым вариантом из комментариев по ссылке Андрея из #2:
Код
Function ГенерацияКлюча(Optional full As Boolean) As String
Do While Len(ГенерацияКлюча) < 32
If Len(ГенерацияКлюча) = 16 Then ГенерацияКлюча = ГенерацияКлюча & Hex$(8 + CInt(Rnd * 3))
ГенерацияКлюча = ГенерацияКлюча & Hex$(CInt(Rnd * 15))
Loop
If full Then ГенерацияКлюча = "{" & Mid$(ГенерацияКлюча, 1, 8) & "-" & Mid$(ГенерацияКлюча, 9, 4) & "-" & Mid$(ГенерацияКлюча, 13, 4) & "-" & Mid$(ГенерацияКлюча, 17, 4) & "-" & Mid$(ГенерацияКлюча, 21, 12) & "}": Exit Function
ГенерацияКлюча = Mid$(ГенерацияКлюча, 1, 8) & Mid$(ГенерацияКлюча, 9, 4) & Mid$(ГенерацияКлюча, 13, 4) & Mid$(ГенерацияКлюча, 17, 4) & Mid$(ГенерацияКлюча, 21, 12)
End Function
дело в том, что, после одного из обновлений, на строке CreateObject("Scriptlet.TypeLib") возникает ошибка (подробности тут).
Чтобы не писать функцию с декларированием библиотек (типа Declare Function CoCreateGuid Lib "ole32" (ByRef GUID As Byte) As Long) и был выбран код выше, как полноценная замена. Вариант от AAF очень хорош, но это не GUID и полезен в других областях (возникают проблемы с длинными числами и их отображением - не хотелось возится)
Знаю, что тема старая, но мне была полезна, да и нечастый вопрос, собственно
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
Снова вернулся к теме, т.к. вариант из предыдущего поста, как оказывается, генерит большое количество дублей уже на тысячах ключей, если диапазон заполняется не одновременно, а в разное время. Вариант от AAF такое исключает (если не править настройки даты/времени на ПК), т.к. привязан к постоянному счётчику. К тому же, возможность узнать дату и время получения ключа также может пригодиться
Добавил префикс для избавления от "длинных" чисел…
Код
Function ГенерацияКлюча() As String
Static idn#, temp#
temp = Fix(Now * 10000000000#)
If idn < temp Then
idn = temp: ГенерацияКлюча = "PRDX" & temp
Else
idn = idn + 1: ГенерацияКлюча = "PRDX" & idn
End If
End Function
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄