powered by simpleCommunicator - 2.0.60     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / FoxPro, Visual FoxPro [игнор отключен] [закрыт для гостей] / Партии
7 сообщений из 7, страница 1 из 1
Партии
    #32961268
Серж-1
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
У меня возникла следующая ситуация, помогите мне её решить.
У нас на складах ведется учот метериалов по партиям. Из года в год она увеличивается. Загод у нас примерно 99 000 тис. партий. Партии уже перевалили за 1 000 000. Как мне зделать так чтобы партии были не длинее 5-ти знаков, но чтобы были уникальными.
Или может ктото предложит чтото свое.
Заранее спасибо.
...
Рейтинг: 0 / 0
Партии
    #32961292
Фотография Hel!Riser
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
************* FUNCTION NewID
*****************************************************************************
* Описание : Создание суррогатного первичного ключа в 36-ричной
* системе исчисления символьного типа.
* Необходимо: Таблица SYSTEM со структурой TagName (C10) ASC; UPPER,
* Value (C{самое_длинное_ключевое_поле_в_БД})
* Значение ключа - существующее значение поля SYSTEM.VALUE
* Таблица system остается открытой
* Параметры : Псевдоним таблицы, для которой генерируется ключ.
* Если параметр опущен - генерируется ключ для текущей таблицы
* Возрат : lcID {символьное значение}
*****************************************************************************
*----------------------------------------------------------------------------
* Внесены изменения:
* В БД system добавлено поле TYPE
* если оно равно "HEX" вызывается процедура генерации 36-ричного ключа
* если оно равно "DEC" вызывается процедура генерации целого ключа "counter"
* если оно равно "STR" вызывается процедура генерации 10-ричного ключа
*
PARAMETER tcAlias, tcSystemAlias, tlNoDelay

PRIVATE lcAlias, lcID, lcOldReprocess, lnOldArea, lnID, M.n_sec

lnOldArea=SELECT()

IF PARAMETERS()<1
lcAlias=UPPER(ALIAS())
ELSE
lcAlias=UPPER(tcAlias)
ENDIF
IF EMPTY(tcSystemAlias)
tcSystemAlias="SYSTEM"
ENDIF

lcID=''
lcOldReprocess=SET('REPROCESS')
SET REPROCESS TO AUTOMATIC

IF !USED(tcSystemAlias)
USE system.dbf IN 0 AGAIN ALIAS (tcSystemAlias)
ENDIF
SELECT (tcSystemAlias)
SET ORDER TO TagName

* задержка в 1 сек. перед взятием нового ключа
* для обновления данных в таблице system
* от других пользователей

IF !tlNoDelay
M.n_sec=SECONDS()
DO WHILE SECONDS()-M.n_sec < 1
ENDDO
ENDIF

IF SEEK(lcAlias,tcSystemAlias,'tagname')
IF RLOCK()
DO CASE
CASE &tcSystemAlias..type="HEX"
lcID=ALLTRIM(&tcSystemAlias..value)
REPLACE &tcSystemAlias..value WITH GenerateKey(ALLTRIM(&tcSystemAlias..value)) && процедура генерации ключа
CASE &tcSystemAlias..type="DEC"
lcID=INT(VAL(&tcSystemAlias..value))
REPLACE &tcSystemAlias..value WITH PADL(lcID+1,FSIZE("value"),"0")
CASE &tcSystemAlias..type="STR"
lcID=ALLTRIM(&tcSystemAlias..value)
lnID=INT(VAL(&tcSystemAlias..value))
REPLACE &tcSystemAlias..value WITH PADL(lnID+1,LEN(lcID),"0")
OTHERWISE && аналог "HEX"
lcID=ALLTRIM(&tcSystemAlias..value)
REPLACE &tcSystemAlias..value WITH GenerateKey(ALLTRIM(&tcSystemAlias..value)) && процедура генерации ключа
ENDCASE
UNLOCK
ELSE
=Islocked()
=Alert("Не могу заблокировать таблицу генерации ключей!"+;
" Генерация нового ключа сейчас невозможна")
ENDIF
ELSE
INSERT INTO (tcSystemAlias) (tagname, value, type) ;
VALUES (lcAlias, PADL("0",FSIZE("value"),"0"), "HEX")
lcID=ALLTRIM(&tcSystemAlias..value)
REPLACE &tcSystemAlias..value WITH GenerateKey(ALLTRIM(&tcSystemAlias..value)) && процедура генерации ключа
=Alert("Таблица "+lcAlias+" не найдена в БД генерации ключей. "+ ;
"Новая запись была создана автоматически. Сообщите разработчикам!")
ENDIF

FLUSH

SELECT (lnOldArea)
SET REPROCESS TO lcOldReprocess
RETURN lcID


***************************************************************************
* Непосредственная генерация 36-ричного значения
***************************************************************************
FUNCTION GenerateKey
PARAMETERS tcValue
#DEFINE NINE 57 && ASC('9')
#DEFINE CAP_Z 90 && ASC('Z')
#DEFINE LOW_Z 122 && ASC('z')
#DEFINE KEY_SPACE 32 && ASC(' ')

PRIVATE lnDigit, lnStringLenght, lnChar, lcCar, lcID, lcValue

lcValue=tcValue
lcID=''

* Цикл обратного просмотра ключа для увеличения его на 1
lnStringLength=LEN(lcValue)
FOR lnDigit=lnStringLength TO 1 STEP -1
lnChar=ASC(SUBSTR(lcValue,lnDigit,1))
IF lnChar=CAP_Z && 36-ричная система
lcValue=LEFT(lcValue,lnDigit-1)+ ;
'0'+RIGHT(lcValue,lnStringLength-lnDigit)
ELSE
DO CASE
CASE lnChar=NINE
lcChar='A'
CASE lnChar=CAP_Z
lcChar='a'
CASE lnChar=KEY_SPACE
lcChar='1'
OTHERWISE
lcChar=CHR(lnChar+1)
ENDCASE
lcID=LEFT(lcValue,lnDigit-1)+ ;
lcChar+ ;
RIGHT(lcValue,lnStringLength-lnDigit)
EXIT
ENDIF
ENDFOR

IF EMPTY(lcID)
lcID=REPLICATE('0',lnStringLength-1)+'1'
ENDIF
RETURN lcID
...
Рейтинг: 0 / 0
Партии
    #32961302
Фотография Hel!Riser
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: 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.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
************* FUNCTION NewID
*****************************************************************************
* Описание	:	Создание суррогатного первичного ключа в  36 -ричной
*				системе исчисления символьного типа.
* Необходимо:	Таблица SYSTEM со структурой TagName (C10) ASC; UPPER,
*				Value (C{самое_длинное_ключевое_поле_в_БД})
*				Значение ключа - существующее значение поля SYSTEM.VALUE
*               Таблица system остается открытой
* Параметры	:	Псевдоним таблицы, для которой генерируется ключ.
*				Если параметр опущен - генерируется ключ для текущей таблицы
* Возрат	: 	lcID {символьное значение}
*****************************************************************************
*----------------------------------------------------------------------------
* Внесены изменения:
* В БД system добавлено поле TYPE
* если оно равно "HEX" вызывается процедура генерации  36 -ричного ключа
* если оно равно "DEC" вызывается процедура генерации целого ключа "counter"
* если оно равно "STR" вызывается процедура генерации  10 -ричного ключа
*
PARAMETER tcAlias, tcSystemAlias, tlNoDelay

PRIVATE lcAlias, lcID, lcOldReprocess, lnOldArea, lnID, M.n_sec

lnOldArea=SELECT()

IF PARAMETERS()< 1 
	lcAlias=UPPER(ALIAS())
ELSE
	lcAlias=UPPER(tcAlias)
ENDIF
IF EMPTY(tcSystemAlias)
	tcSystemAlias="SYSTEM"
ENDIF

lcID=''
lcOldReprocess=SET('REPROCESS')
SET REPROCESS TO AUTOMATIC

IF !USED(tcSystemAlias)
	USE system.dbf IN  0  AGAIN ALIAS (tcSystemAlias)
ENDIF
SELECT (tcSystemAlias)
SET ORDER TO TagName

* задержка в  1  сек. перед взятием нового ключа
* для обновления данных в таблице system
* от других пользователей

IF !tlNoDelay
	M.n_sec=SECONDS()
	DO WHILE SECONDS()-M.n_sec <  1 
	ENDDO
ENDIF

IF SEEK(lcAlias,tcSystemAlias,'tagname')
	IF RLOCK()
		DO CASE 
		CASE &tcSystemAlias..type="HEX"
			lcID=ALLTRIM(&tcSystemAlias..value)
			REPLACE &tcSystemAlias..value WITH GenerateKey(ALLTRIM(&tcSystemAlias..value)) && процедура генерации ключа
		CASE &tcSystemAlias..type="DEC"
			lcID=INT(VAL(&tcSystemAlias..value))
			REPLACE &tcSystemAlias..value WITH PADL(lcID+ 1 ,FSIZE("value"),"0")
		CASE &tcSystemAlias..type="STR"
			lcID=ALLTRIM(&tcSystemAlias..value)
			lnID=INT(VAL(&tcSystemAlias..value))
			REPLACE &tcSystemAlias..value WITH PADL(lnID+ 1 ,LEN(lcID),"0")
		OTHERWISE	&& аналог "HEX"
			lcID=ALLTRIM(&tcSystemAlias..value)
			REPLACE &tcSystemAlias..value WITH GenerateKey(ALLTRIM(&tcSystemAlias..value)) && процедура генерации ключа
		ENDCASE
		UNLOCK
	ELSE
		=Islocked()
		=Alert("Не могу заблокировать таблицу генерации ключей!"+;
		      " Генерация нового ключа сейчас невозможна")
	ENDIF
ELSE
	INSERT INTO (tcSystemAlias) (tagname, value, type) ;
		VALUES (lcAlias, PADL("0",FSIZE("value"),"0"), "HEX")
	lcID=ALLTRIM(&tcSystemAlias..value)
	REPLACE &tcSystemAlias..value WITH GenerateKey(ALLTRIM(&tcSystemAlias..value)) && процедура генерации ключа
	=Alert("Таблица "+lcAlias+" не найдена в БД генерации ключей. "+ ;
		"Новая запись была создана автоматически. Сообщите разработчикам!")
ENDIF

FLUSH

SELECT (lnOldArea)
SET REPROCESS TO lcOldReprocess
RETURN lcID


***************************************************************************
*	Непосредственная генерация  36 -ричного значения
***************************************************************************
FUNCTION GenerateKey
PARAMETERS tcValue
#DEFINE	NINE		 57 			&& ASC('9')
#DEFINE	CAP_Z		 90 			&& ASC('Z')
#DEFINE	LOW_Z		 122 			&& ASC('z')
#DEFINE	KEY_SPACE	 32 			&& ASC(' ')

PRIVATE lnDigit, lnStringLenght, lnChar, lcCar, lcID, lcValue

lcValue=tcValue
lcID=''

* Цикл обратного просмотра ключа для увеличения его на  1 
lnStringLength=LEN(lcValue)
FOR lnDigit=lnStringLength TO  1  STEP - 1 
	lnChar=ASC(SUBSTR(lcValue,lnDigit, 1 ))
	IF lnChar=CAP_Z		&&  36 -ричная система
		lcValue=LEFT(lcValue,lnDigit- 1 )+ ;
			'0'+RIGHT(lcValue,lnStringLength-lnDigit)
	ELSE
		DO CASE
			CASE lnChar=NINE
				lcChar='A'
			CASE lnChar=CAP_Z
				lcChar='a'
			CASE lnChar=KEY_SPACE
				lcChar='1'
			OTHERWISE
				lcChar=CHR(lnChar+ 1 )
		ENDCASE
		lcID=LEFT(lcValue,lnDigit- 1 )+ ;
			lcChar+ ;
			RIGHT(lcValue,lnStringLength-lnDigit)
		EXIT
	ENDIF
ENDFOR

IF EMPTY(lcID)
	lcID=REPLICATE('0',lnStringLength- 1 )+'1'
ENDIF
RETURN lcID
...
Рейтинг: 0 / 0
Партии
    #32961340
Urri
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
1. Использовать буквенно-цифровые комбинации. По основанию 36 (только цифры и большие латинские буквы) получится 36^5=60466176 - более 60 миллионов уникальных комбинаций. По основанию 62 (добавим маленькие латинские буквы) - 62^5=916132832 - почти 1 миллиард (теоретический предел dbf).
2. Перестроить БД таким образом, чтобы партии были уникальными внутри товарной позиции. Составной ключ код товара+код партии.
3. Увеличить разрядность идентификатора партии.
4. Организовать повторное использование израсходованных партий (не рекомендуется, но возможно).
...
Рейтинг: 0 / 0
Партии
    #32961350
Фотография ВладимирМ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
На всякий случай.

Тип данных Integer физически занимает в памяти 4 байта (4 знака), хотя принимает значения от -2,147,483,647 до 2,147,483,647
...
Рейтинг: 0 / 0
Партии
    #32961544
Sergey Ch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ВладимирМНа всякий случай.

Тип данных Integer физически занимает в памяти 4 байта (4 знака), хотя принимает значения от -2,147,483,647 до 2,147,483,647
...
Рейтинг: 0 / 0
Партии
    #32962055
Igor Korolyov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Hi Серж-1!

Ну ещё есть BINTOC()/CTOBIN() - по сути в 4 знака ТЕКСТОВОГО NOCPTRANS поля поместится число диапазона Integer. Хотя зачем это нужно если можно непосредственно Integer использовать - я не знаю :)

Posted via ActualForum NNTP Server 1.1
...
Рейтинг: 0 / 0
7 сообщений из 7, страница 1 из 1
Форумы / FoxPro, Visual FoxPro [игнор отключен] [закрыт для гостей] / Партии
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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