powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / FoxPro, Visual FoxPro [игнор отключен] [закрыт для гостей] / Курсовая
9 сообщений из 9, страница 1 из 1
Курсовая
    #34615118
korjj
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
У меня вопрос. Мне нужно, чтобы он нашел все записи в таблице POSTUP, где поле DONE2 равно 0. Затем скопировал значения этих записей в полях COD2 NAME2 VOLUME2, установил в них DONE2 в 1. После чего в таблице TOVAR если имеется CODE4 ранвый CODE2 (artikyl) то чтобы он добавил к значению поля PRIXOD значение VOLUME2, для остальных (из выбранных из базы POSTUP) создал новый записси в TOVAR. Но у меня начинается бесконечный цикл.
Я методом копипаста нашёл где начинается этот долбаный бесконечный цикл. Он курсивом в
коде:

USE postup &&IN 100
GO TOP IN postup
DO WHILE NOT EOF('postup')
&&LOCATE FOR &&postup.done2=0

IF postup.done2=0 &&FOUND()
artikyl=postup.code2
naimen=postup.name2
prixod=postup.volume2
replace done2 WITH 1
nom=RECNO('postup')

USE tovar
GO TOP IN tovar
nomer=0
&&&&&&&&&&&&&&&&&&&&&&&&&&& LOCATE FOR code4=artikyl
DO WHILE NOT EOF('tovar')
IF code4=artikyl && IF FOUND()
nomer=RECNO()
ENDIF && Ìîæåò íóæåí ñêèï
&&SET FILTER TO
&&nomer=poisk(artikyl)
GO TOP IN tovar
DO WHILE NOT EOF('tovar')
IF nomer<>0
&&USE tovar &&IN 101
GO nomer
replace tovar.prixod4 WITH prixod
skip
ELSE
&&USE tovar &&IN 101
APPEND BLANK
GO BOTTOM
replace tovar.name4 WITH naimen
replace tovar.code4 WITH artikyl
replace tovar.prixod4 WITH prixod
SKIP
ENDIF
SKIP
ENDDO

SKIP
ENDDO

USE postup &&IN 100
GO nom

ENDIF
SKIP
ENDDO
Помогите плз.
Да, и я понимаю, что вопрос элементарный, что код написан по рабоче-крестьянски, что можно всё сделать гораздо проще, но ввиду того, что времени ну ОЧЕНЬ мало осталось прошу сказать, как исправить мою ошибку, а не как всё сделать проще.
...
Рейтинг: 0 / 0
Курсовая
    #34615157
Dag
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Попробуй сформулировать что тебе нужно более доступно - что у тебя есть и что ты хочешь получить
...
Рейтинг: 0 / 0
Курсовая
    #34615164
korjj
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Ну в идеале мне нужно чтобы код, выделенный курсивом перестал быть бесконечным циклом.
А вообще суть такая:
Есть таблица, в которой сказано что было привезено, POSTUP. Есть таблица того, что уже имеется на складе TOVAR. В таблице POSTUP товары, не учтённые на складе имеют значение поля DONE2 нулевое (соответственно неучтённые 1). Мне нужно, чтобы если неучтённые поступившие товары, и те что на складе совпадают (одинаковые записи в полях CODE2 u CODE4) то он заменил бы в TOVAR для этой записи только 1 поле PRIXOD4 на значение из POSTUP; а если не совпадают, то создал бы новую запись и уже туда ввёл бы новое название товара, код, количество.
Да, это фрагмент обработчика кнопки формирования таблицы TOVAR.
Если из кода вырезать выделенный фрагмент, то ничего не виснет. Всё выполняется как надо (кроме разумеется замены поля ПРИХОД4 и создания новой записи в ТОВАР)
...
Рейтинг: 0 / 0
Курсовая
    #34615209
Dag
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Попробуй

SELECT postup
GO TOP

DO WHILE NOT EOF('postup')
IF postup.done2=0
artikyl=postup.code2
naimen=postup.name2
prixod=postup.volume2
replace done2 WITH 1

SELECT tovar
GO TOP IN tovar
LOCATE FOR code4==artikul
IF FOUND()
replace tovar.prixod4 WITH prixod
ELSE
APPEND BLANK
replace tovar.name4 WITH naimen
replace tovar.code4 WITH artikyl
replace tovar.prixod4 WITH prixod
ENDIF

ENDIF
SELECT postup
SKIP IN postup
ENDDO
****************************
...
Рейтинг: 0 / 0
Курсовая
    #34615509
korjj
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
всё равно зацикливается =(
...
Рейтинг: 0 / 0
Курсовая
    #34615566
BMJ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
BMJ
Гость
Выясните где циклится.
Вставьте счетчик переходов
i=i+1 при каждом вхождении в таблицу товар
будет видно переходите ли из таблицы в таблицу, а по счетчику увидите движение в таблице
т.е. ? alias()+' запись'+str(i)
это после DO WHILE
после SELE postul
IF
wait wind 'Существует' TIMEOUT 10 NOWAIT
ELSe
wait wind 'Добавляется' TIMEOUT 10 NOWAIT
ENDIF
...
Рейтинг: 0 / 0
Курсовая
    #34615667
Dag
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Можно выбросить весь обрабатывающий код и выполнить конструкцию
SELECT postup
GO TOP
DO WHILE NOT EOF('postup')

SELECT postup
SKIP IN postup

ENDDO

Если и при этом попадете в цикл - то даже не знаю что думать.
...
Рейтинг: 0 / 0
Курсовая
    #34615711
Фотография ВладимирМ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
1. Для сканирования записей таблиц существует цикл SCAN...ENDSCAN. Т.е. вместо

Код: plaintext
1.
2.
3.
4.
5.
6.
USE postup &&IN  100 
GO TOP IN postup
DO WHILE NOT EOF('postup')
...
SKIP 
ENDDO 

Используется такая конструкция

Код: plaintext
1.
2.
3.
4.
5.
6.
SELECT  0 
USE postup
GO TOP
SCAN
...
ENDSCAN

Цикл SCAN сам бедет перебирать все записи до конца и сам же завершит выполнение, когда этот самый конец будет достугнут.

2. Команда USE открывает таблицу. Делает ее "видимой" для FoxPro. При этом, та же самая команда закрывает таблицу, открытую в той же рабочей области. Переключение между ранее открытыми таблицами осуществялется командой SELECT

Код: plaintext
1.
2.
USE postup IN  0 	&& Открыли таблицу в первой попавшейся свободной рабочей области
SELECT postup	&& Переключились в рабочую область с алиасом postup

Если дать команду вида

Код: plaintext
USE postup

То это означает закрыть ту таблицу, которая была ранее открыта в текущей рабочей области и в этой же, текущей рабочей области открыть таблицу postup

"Дергать" команду USE внутри циклов перебора записей этой же таблицы - довольно глупое и опасное занятие. Обычно все необходимые таблицы открывают ДО того, как начинают перебирать записи и таблицу уже не закрывают до окончания циклов.

Т.е. в даном случае начало должно выглядеть примерно так:

Код: plaintext
1.
2.
3.
4.
5.
6.
Use postup IN  0 
Use tovar IN  0 

select postup
SCAN
...
ENDSCAN

Никакие USE внутри цикла недопустимы.

3. У Вас задача формулируется так: для одной записи таблицы postup найти одну запись в таблице tovar, а если такой записи найдено не будет, то создать запись в таблице tovar.

Зачем здесь перебор ВСЕХ записей в таблице tovar? Тем более, приводящий к явному зацикливанию? Бесконечному APPEND BLANK? Вам надо найти ОДНУ запись или убедится что такой записи не существует. Для этого есть команды LOCATE и SEEK (если есть соответсвующие индексы).

Если исходить из предположения, что в таблице TOVAR значение поля CODE4 уникально, т.е. может существовать одна и только одна запись с одним и тем же значением поля CODE4, то цикл будет выглядеть так:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
Use postup IN  0 
Use tovar IN  0 

select postup
* Очень важно сбросить главный индекс, поскольку внутри SCAN
* меняется значение поля по которому идет отбор
SET ORDER TO  0 
SCAN FOR postup.done2 =  0 		&& Сканируем только не учтенные записи
	SELECT tovar
	LOCATE FOR tovar.Code4 = postup.Code2
	IF FOUND('tovar')
		* Нашли запись в таблице tovar. Изменяем ее
		REPLACE prihod4 WITH postup.volume2
	ELSE
		* Записи нет. Ее надо создать
		INSERT INTO tovar (code4, name4, prihod4) ;
			VALUES (postup.Code2, postup.name2, postup.volume2)
	ENDIF
	* Изменяем признак 
	select postup
	REPLACE done2 WITH  1 
ENDSCAN

Если в таблице TOVAR может быть более чем одна запись с одним и тем же значением поля Code4, то вместо LOCATE придется использовать еще один вложенный цикл, внутри которого выставлять флаг, что были внутри цикла и по этому флагу принимать решение о создании новой записи.

Хотя во всем этом алгоритме непонятно, почему значение из таблицы postup замещает зеначение в таблице tovar, хотя, по идее, должно было прибавлять к тому, что уже есть. Наращивать значение.
...
Рейтинг: 0 / 0
Курсовая
    #34617287
korjj
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Ну во-первых всем СПАСИБО что откликнулись, помогли.
Особенно благодарен ВладимирМ'у за столь полный и содержательный ответ. Приведённый код не только решил эту проблему, но и все мои проблемы с зацикливанием.
Дело в том, что с фокспро я начал "работать" около недели назад, поэтому то и не знал, про тонкости СЕЛЕКТА и ЮЗА, и уж вообще не знал про СКАН.
Да, и если интересно, зацикливание было не на апеенд бланке, а на реплейсе (от чего кстати не нмного легче). Записи поля КОД действительно уникальны(для одной таблицы). Значение замещается, а не прибавляется потому, что формируется не поле КОНЕЧНЫЙ ОСТАТОК а ПРИХОД. КОНЕЧНЫЙ ОСТАТОК будет равен НАЧАЛЬНЫЙ ОСТАТОК+ПРИХОД-РАСХОД.

ps ещё раз повторю, что я очень плохо разбираюсь в фокспро, поэтому, я уверен, всё можно было сделать и проще. Не ломайте голову над этим вопросом ;)
pps не ответил сразу, потомучто был занят доведением до ума работы, теперь вот ответил.

ДАННОЙ ПРОБЛЕМЫ БОЛЬШЕ НЕ СУЩЕСТВУЕТ
...
Рейтинг: 0 / 0
9 сообщений из 9, страница 1 из 1
Форумы / FoxPro, Visual FoxPro [игнор отключен] [закрыт для гостей] / Курсовая
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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