Ну, у вас есть длинный вопрос, содержащий несколько вопросов.Я постараюсь ответить по частям (редактируя мой промежуточный ответ), так как это будет длинный ответ (может быть даже полезно разделить его на несколько ответов).
Во-первых, синтаксис создания таблицы был близок, но неверен,VFP (кстати, это не VFB, а V FP), не поддерживает пробелы в именах полей (если это не длинное имя поля).Использование имен полей с пробелами будет просто проблемой.Поэтому предпочитаю не использовать их.Это будет выглядеть так:
CREATE TABLE tableA;
( id int, ;
balance double, ;
load C(240), ;
state C(240))
CREATE TABLE tableB;
( Load id int, ;
id int, ;
ord int, ;
fact double, ;
type int ;
firstValue C(240),;
roundedVal C(240), ;
state C(240))
Обратите внимание, что после последнего поля у вас нет запятой и;в VFP означает продолжить команду на следующей строке (поэтому удалено в последних строках определения поля).Я также изменил имена двух полей, чтобы они были совместимы с именами полей свободной таблицы (максимум 10 по длине и должны начинаться с буквы, без пробелов).Проще использовать таблицы таким способом. Или курсорами, если вы делаете это за один раз и не пытаетесь изменить структуру позже.
Если вы хотите использовать длинные имена полей, вы можете сделать это так же, как и с бесплатнымитаблицы, но таблица должна быть частью базы данных.Это также будет работать для курсоров, если вы сделаете это за один раз и не будете пытаться изменить структуру впоследствии.
Хотя я добавил туда код для создания TableA, TableB, вы говорите, что данные этих таблиц будут получены изExcel.Вы на самом деле не предоставили подробную информацию о его части в Excel (как данные представлены - это диапазоны данных?).Существует большая вероятность, что вы создадите эти две таблицы, просто выбрав данные из Excel, используя ODBC / OLEDB напрямую.
Для получения данных из Excel я разместил подробную информацию о Foxite, вы можете проверитьпост в этой ссылке .Я не даю здесь никакого примера кода, так как на самом деле я еще не знаю часть Excel.
Предполагая, что мы получили данные из Excel, давайте проверим другие части (кстати, в таблице B id называется внешним ключом, а неосновной. Он связывает строки в верхней части TableB (TableA).
1st value[i] = If(Type[i]=0, balance[i]*fact[i], balance[i]*fact[i]/(1-fact[i]))
Мы можем использовать либо команду REPLACE (команда xBase), либо команду SQL Update, чтобы выполнить это.Давайте не будем думать о различиях здесь (на самом деле не стоит) и выберем SQL Update для выполнения работы (синтаксис можно будет использовать повторно и в других базах данных - скажем, MS SQL server, postgreSQL, mySQL ...).
Update tableB ;
set firstValue = iif( type = 0, ;
tableA.balance * fact, ;
tableA.balance * fact/(1-fact)) ;
from tableA ;
where tableA.Id = tableB.Id
Или немного упрощенно:
Update tableB ;
set firstValue = tableA.balance * fact / ;
iif( type = 0, 1, (1-fact)) ;
from tableA ;
where tableA.Id = tableB.Id
Обратите внимание, что VFP будет выполнять это выражение для каждой строки, поэтому нам не нужен [i] (идентификатор массива), который есть в вашем псевдокоде.
Следующий:
rounded value[i] = If(Type[i]>0, rounddown(1st value[i], 1), roundup(1st value[i],2)
Будет переведен таким же образом:
Update tableB ;
set roundVal = iif(type > 0, ;
rounddown(firstValue,1), ;
roundup(firstValue,2)) ;
from tableA ;
where tableA.Id = tableB.Id
Однако VFP не имеет функций округления и округления, я написал их только как концептуальныеперевод.Что вы можете сделать, это создать две пользовательские функции, которые делают RoundUp и RoundDown.Есть несколько способов написания этих функций, и имхо проще всего было бы написать их как 2 отдельных файла .prg, где эти prg-файлы находятся в вашем пути поиска, когда вы выполняете указанную выше команду SQL:
RoundUp.prg
Lparameters tnValue, tnPlaces
If Round(m.tnValue, m.tnPlaces) = m.tnValue
Return m.tnValue
Else
Return Round(m.tnValue+((10^-(m.tnPlaces+1))*5), m.tnPlaces)
Endif
RoundDown.prg
Lparameters tnValue, tnPlaces
If Round(m.tnValue, m.tnPlaces) = m.tnValue
Return m.tnValue
Else
Return Round(m.tnValue-((10^-(m.tnPlaces+1))*5), m.tnPlaces)
Endif
Функции, указанные в приведенной вами ссылке, мне не подходят для работы (но его было непросто понять и проверить, поэтому я не тратил время на тщательную проверку).
Я не уверен, что один лист, содержащий обе таблицы, подходит.Я не могу вспомнить, если бы коллекция таблиц была членом WorkSheet или WorkBook.Если WorkSheet, то это будет делать.Я могу проверить и написать пример кода для этого позже (возможно, завтра).
Вы можете использовать тип данных LOGICAL (l) для Типа.В MS SQL сервере и других бэкэндах он соответствует биту (1 или 0).Внутренне хранится как логическое значение, но в выражениях используется как .T ./. F.(символьное представление true \ false в VFP. В коде вы можете просто использовать его как:
iif( type, ...
то же самое, что сказать iif (type = .T., ...) - как в Type> 0. И:
iif( !type, ...
тоже самое, что сказать iif (type = .F., ...) или iif (type NOT равно .T., ... - как в Type = 0.
В этом случае я не использовал внутреннее соединение, потому что здесь достаточно использовать таблицу А из таблицы А (то же самое в других бэкэндах, хотя общая тенденция состоит в том, чтобы писать это с использованием соединения).
РЕДАКТИРОВАТЬ:Добавил код в качестве другого ответа.
По вашим вопросам: Внутреннее объединение не требуется для явного определения, здесь есть неявное объединение.Вместо того, чтобы писать обновление SQL, я предпочел использовать возможности VFP xBase и вместо этого использовать scan ... endcan (может быть с SQL, но будет более сложным).
Да, это означает, что эти 2 RoundUp.prg иФайл RoundDown.prg попадает в тот же путь к каталогу нашего основного файла, что и выше, НО, только если код основного файла находится в текущем каталоге или в пути поиска.Чтобы сделать это более понятным, рассмотрим:
c: \ SomeFolder \ RoundUp.prg c: \ SomeFolder \ RoundDown.prg c: \ ANOTHERFolder \ Main.prg
, и вы находитесь в: c: \ YetAnotherFolder
Если вы вызываете main.prg следующим образом:
do ('c:\ANOTHERFolder\Main.prg')
Он должен найти RoundUp, RoundDown и может, если c: \ Somefolder включен в SET ('PATH')) - т.е.:
Set path to c:\SomeFolder;c:\VFPHomeFolderMaybe
Или, если вы не хотите думать о маршрутизации, вы можете включить этот код RoundUp \ Down как процедуру в код (как я сделал в коде в другом ответе - примечаниечто в VFP нет никакой разницы между PROCEDURE и FUNCTION. Вы можете выбрать любой из них. Некоторые разработчики предпочитают использовать FUNCTION для тех, которые возвращают значение - но на самом деле любой PROCEDURE \ FUNCTION возвращает значение, поэтому, скажем, те, которыеиспользуются для возвращаемого значения.)
Я не думаю, что логический тип автоматически означает «1» или «0», правильно?Если это так, я бы оставил его как тип int, потому что для столбца типа вход всегда определяется как 1 или 0.
Хорошо, формально сложно ответить.В VFP логический тип данных определяется литералами .F.и т.Вы можете разыграть (от aBoolean до int), и вы получите 0 и 1 соответственно.Или вы можете разыграть (1 как логическое), чтобы получить .T.IOW 1 \ 0 и .T..F.являются взаимозаменяемыми в некотором смысле.Все зависит от того, где вы хотите его использовать.Если данные поступают из внешнего источника, они поступают как 1 \ 0.Просто приведение или получение его в столбце логического типа данных (неявное приведение) обрабатывается как .T..F.Или вы отправляете данные из логического во внешний источник (например, XML, сервер MS SQL, postgreSql, другой источник данных OLEDB \ ODBC), а затем .T..F.кастуется как 1 \ 0.