Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Методичка 5 Справка в VFP Обработка ошибок Отла...doc
Скачиваний:
1
Добавлен:
20.08.2019
Размер:
2.18 Mб
Скачать

2.2.2.Логічні помилки

Це друга категорія помилок з нашого переліку. Знайти їх набагато важче, ніж синтаксичні. Вони ніколи не виявляються на стадії компіляції. Існують серйозні логічні помилки, що приводять до зупинки програми: наприклад, посилання на неіснуючий масив чи елемент неіснуючого масиву приведуть до припинення виконання програми в результаті логічної помилки. Можливо, що масив і оголошений в іншій процедурі (файлі програми), але має зону видимості тільки цього файлу, а тому і вважається неіснуючим в інших компонентах проекту. Коли Visual FoxPro виявляє звертання до неіснуючого масиву чи перемінної, виконання додатка припиняється.

Більшість логічних помилок приводить просто до невірних результатів виконання програми: наприклад, у деякому полі таблиці ви можете знайти кілька символів “зірочка” (****), що означає переповнення поля. У цьому випадку або розмір поля обраний невиправдано малим, або обчислене значення занадто велике. Звичайно, не завжди помилки мають такі драматичні наслідки. Якщо в звіті про продажі розрахований сумарний податок, що перевищує вартість придбаних товарів, то в компанії можуть виникнути проблеми. Ця помилка дуже просто виявляється при порівнянні сумарної вартості продажів до і після нарахування податків. З іншого боку, багато помилок (точніше, їхні наслідки) не так очевидні. Часто приходиться якимось незалежним способом перевіряти ще раз результати розрахунків. Припустимо, для розрахунку площі прямокутної земельної ділянки в акрах використовується наступне вираження: gnTotalAcres = (pnFront * pnSіde)/9/4480

Це на перший погляд цілком коректне вираження, що не викликає ніяких помилок при виконанні. Перемножується довжина і ширина, задані у футах. Результат — площа в квадратних футах. Потім він поділяється на 9 — кількість квадратних футів на квадратний ярд. А потім поділяється на кількість квадратних ярдів на акр, але цей показник набраний у програмі невірно — замість 4840 набране 4480. Глянувши на результат, ви навряд чи догадаєтеся, що у вираженні в програмі переплутані місцями дві цифри. Такого типу помилки дуже довго можуть залишатися в програмі (поки в один прекрасний день у компанію з продажу нерухомості, що користалася цією програмою, не прийдуть розсерджені клієнти…).

Інший розповсюджений тип логічних помилок, що виявляються важко, зв'язаний з використанням команди REPLACE. Припустимо, ви хочете змінити значення в деякім полі однієї таблиці, у той час як покажчик у поточній таблиці вказує на кінець файлу (EOF).

SELECT cust

IF! SEEK (m.pcCustId)

REPLACE order.cCustld WITH 'NONE'

ENDIF

На перший погляд здається, що в цьому фрагменті немає ніяких підводних каменів, але програма зупинилася. Після того як Visual FoxPro спробує знайти ідентифікатор покупця в таблиці cust і не зможе, що поточний покажчик буде вказувати на кінець таблиці. Хоча команда REPLACE і використовує явне ім'я псевдоніма для заміни значення cCustld у таблиці order, за замовчуванням область видимості для NEXT 1 у дійсності включає поточну робочу область, тобто cust, a аж ніяк не order. Оскільки в цій області покажчик указує на кінець таблиці (EOF), команда REPLACE виконана не буде. Вихід із ситуації в тім, щоб перед REPLACE6 вставити оператор SELECT order.

Оскільки Visual FoxPro не вимагає обов'язково вказувати ім'я псевдоніма робочої області перед ім'ям поля, іноді з тексту програми не ясно, виконується операція з полем таблиці чи з перемінною в пам'яті. Для присвоєння нового значення перемінної в пам'яті використовується вираження присвоєння зі знаком рівності (=), а для введення нового значення в поле таблиці — команда REPLACE. Якщо в розглянутому операторі використовувати вираження присвоєння, то виконавча система Visual FoxPro його спокійно “проковтне”, але результат буде дуже далекий від очікуваного, оскільки значення буде привласнено не полю таблиці, а перемінної в пам'яті з тим же ім'ям: cCustld = 'NONE'