Foxpro открыть файл excel

Source: Microsoft Support

RAPID PUBLISHING

RAPID PUBLISHING ARTICLES PROVIDE INFORMATION DIRECTLY FROM WITHIN THE MICROSOFT SUPPORT ORGANIZATION. THE INFORMATION CONTAINED HEREIN IS CREATED IN RESPONSE TO EMERGING OR UNIQUE TOPICS, OR IS INTENDED SUPPLEMENT OTHER KNOWLEDGE BASE INFORMATION.

Action

You have a Microsoft Excel 2007 workbook (.XLSX). You want to import data from it into a Microsoft Visual FoxPro (VFP) table using VFP.

Resolution

There are a number of ways of accomplishing this task:

1. Export the Excel sheet(s) as comma delimited files (.CSV) and use the IMPORT command or the Import Wizard inside VFP to import the file(s).

2. Write custom VFP OLE automation code to automate Excel and extract the data to VFP.

3. Use the Microsoft Excel Driver (*.xls, *.xlsx, *.xlsm, *.xlsb) ODBC driver included with the 2007 Office System Driver: Data Connectivity Components package to access and extract data from the Excel workbook, either through a VFP Remote View or programmatically, as in the following sample code:

*————————————
* AUTHOR: Trevor Hancock
* CREATED: 02/15/08 04:55:31 PM
* ABSTRACT: Code demonstrates how to connect to
* and extract data from an Excel 2007 Workbook
* using the «Microsoft Excel Driver (*.xls, *.xlsx, *.xlsm, *.xlsb)»
* from the 2007 Office System Driver: Data Connectivity Components
*————————————
LOCAL lcXLBook AS STRING, lnSQLHand AS INTEGER, ;
    lcSQLCmd AS STRING, lnSuccess AS INTEGER, ;
    lcConnstr AS STRING
CLEAR

lcXLBook = [C:SampleWorkbook.xlsx]

lcConnstr = [Driver=] + ;
    [{Microsoft Excel Driver (*.xls, *.xlsx, *.xlsm, *.xlsb)};] + ;
    [DBQ=] + lcXLBook

IF !FILE( lcXLBook )
    ? [Excel file not found]
    RETURN .F.
ENDIF
*— Attempt a connection to the .XLSX WorkBook.
*— NOTE: If the specified workbook is not found,
*— it will be created by this driver! You cannot rely on a
*— connection failure — it will never fail. Ergo, success
*— is not checked here. Used FILE() instead.
lnSQLHand = SQLSTRINGCONNECT( lcConnstr )

*— Connect successful if we are here. Extract data…
lcSQLCmd = [Select * FROM «Sheet1$»]
lnSuccess = SQLEXEC( lnSQLHand, lcSQLCmd, [xlResults] )
? [SQL Cmd Success:], IIF( lnSuccess > 0, ‘Good!’, ‘Failed’ )
IF lnSuccess < 0
    LOCAL ARRAY laErr[1]
    AERROR( laErr )
    ? laErr(3)
    SQLDISCONNECT( lnSQLHand )
    RETURN .F.
ENDIF

*— Show the results
SELECT xlResults
BROWSE NOWAIT
SQLDISCONNECT( lnSQLHand )

DISCLAIMER

MICROSOFT AND/OR ITS SUPPLIERS MAKE NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY, RELIABILITY OR ACCURACY OF THE INFORMATION CONTAINED IN THE DOCUMENTS AND RELATED GRAPHICS PUBLISHED ON THIS WEBSITE (THE “MATERIALS”) FOR ANY PURPOSE. THE MATERIALS MAY INCLUDE TECHNICAL INACCURACIES OR TYPOGRAPHICAL ERRORS AND MAY BE REVISED AT ANY TIME WITHOUT NOTICE.

TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, MICROSOFT AND/OR ITS SUPPLIERS DISCLAIM AND EXCLUDE ALL REPRESENTATIONS, WARRANTIES, AND CONDITIONS WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING BUT NOT LIMITED TO REPRESENTATIONS, WARRANTIES, OR CONDITIONS OF TITLE, NON INFRINGEMENT, SATISFACTORY CONDITION OR QUALITY, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, WITH RESPECT TO THE MATERIALS.

Need more help?

Want more options?

Explore subscription benefits, browse training courses, learn how to secure your device, and more.

Communities help you ask and answer questions, give feedback, and hear from experts with rich knowledge.

  • Исходный макрос Excel
  • Открытие листа Excel в FoxPro
  • Подключение механизма IntelliSens в FoxPro
  • Метод Select
  • Указание диапазона ячеек для функции
  • Указание произвольного диапазона ячеек
  • Когда использовать «запятую», а когда «точку с запятой»
  • Указание формата ячеек
  • Константы Excel
  • Именованные параметры функций Excel
  • Рисование рамки вокруг всех данных
  • Перенос слов, выравнивание, ширина столбца и высота строки

Вы вероятно уже знаете, что для того, чтобы определить как именно (какой командой) в Excel можно сделать то или иное проще всего выполнить это действие прямо в Excel с одновременной записью Ваших действий.

Для этого выбирается пункт меню Excel с именем «Сервис» — «Макрос» — «Начать запись». В появившемся окне указываем имя макроса (по умолчанию «Макрос1») и нажимаем кнопку «Ok». В результате, поверх листа Excel появляется маленькое специфическое окошко — ToolBar — с именем «Остановить запись» и все Ваши действия будут автоматически записываться.

После того, как Вы выполните все необходимые действия, остановите запись макроса. Для этого просто нажмите иконку с черным квадратиком в этом ToolBar с именем «Остановить запись». Далее выберите пункт меню Excel с именем «Сервис» — «Макрос» — «Макросы». Выберите имя только что записанного макроса (по умолчанию «Макрос1») и нажмите кнопку «Изменить».

Откроется окно редактора Micosoft Visual Basic в котором будет отображен код Вашего макроса. Это все замечательно, но возникает вопрос: как перевести то, что здесь написано в синтаксис FoxPro? И как вообще использовать это в FoxPro? Вот ответам на эти вопросы и посвящена данная статья.

Сразу замечу, что почти без изменений все приведенные советы можно применить к Word. Для примера выбран Excel потому, что в нем проще адресация. Весь лист разбит на ячейки, к которым собственно и ссылаемся.

Исходный макрос Excel

Сначала собственно создадим макрос, переводом которого позже и займемся. Откройте Excel, создайте новый файл и запустите запись макроса через пункт меню «Сервис» — «Макрос» — «Начать запись». Имя макроса оставьте в значении по умолчанию «Макрос1» и нажмите кнопку «Ok».

Далее заполняем лист Excel таким содержимым

Названиереквизита Значениереквизита
Первый 1 234,56
Второй 9 876,54
ИТОГО 11 111,10

Здесь сделано следующее:

  • Вся первая и последняя строка выделены жирным шрифтом
  • Содержимое всех ячеек первой строки переносится по словам
  • Для второго столбца установлен формат данных: числовой, два знака после запятой, пробел между тройками чисел
  • Также для второго столбца, точнее, только для числовых ячеек, установлен условный формат: выделить фон ячейки красным, если его содержимое меньше 2000
  • Последняя строка второго столбца содержит формулу суммирования содержимого всех строк таблицы по второму столбцу
  • Все заполненные ячейки обрамлены сеткой

Останавливаю запись макроса и смотрю, что же у меня получилось. Пункт меню «Сервис» — «Макрос» — «Макросы». Выбираю имя только что записанного макроса «Макрос1» и нажимаю кнопку «Изменить».

Sub Макрос1()
'
' Макрос1 Макрос
' Макрос записан 10.05.2005 (Максимов)
'

'
'   Ввод содержимого ячеек
    ActiveCell.FormulaR1C1 = "Название реквизита"
    Range("B1").Select
    ActiveCell.FormulaR1C1 = "Значение реквизита"
    Range("A2").Select
    ActiveCell.FormulaR1C1 = "Первый"
    Range("B2").Select
    ActiveCell.FormulaR1C1 = "1324.56"
    Range("A3").Select
    ActiveCell.FormulaR1C1 = "Второй"
    Range("B3").Select
    ActiveCell.FormulaR1C1 = "9876.54"
    Range("A4").Select
    ActiveCell.FormulaR1C1 = "ИТОГО"

'   Формула расчета итога
    Range("B4").Select
    ActiveCell.FormulaR1C1 = "=SUM(R[-2]C:R[-1]C)"

'   Выделение первой и последней строк жирным шрифтом
    Range("1:1,4:4").Select
    Range("A4").Activate
    Selection.Font.Bold = True

'   Установка формата для второго столбца
    Columns("B:B").Select
    Selection.NumberFormat = "#,##0.00"

'   Установка условного формата для числовых данных второго столбца
    Range("B2:B4").Select
    Selection.FormatConditions.Delete
    Selection.FormatConditions.Add Type:=xlCellValue, Operator:=xlLess, _
        Formula1:="2000"
    Selection.FormatConditions(1).Interior.ColorIndex = 3

'   Рисование рамки вокруг всех данных
    Range("A1:B4").Select
    Selection.Borders(xlDiagonalDown).LineStyle = xlNone
    Selection.Borders(xlDiagonalUp).LineStyle = xlNone
    With Selection.Borders(xlEdgeLeft)
        .LineStyle = xlContinuous
        .Weight = xlThin
        .ColorIndex = xlAutomatic
    End With
    With Selection.Borders(xlEdgeTop)
        .LineStyle = xlContinuous
        .Weight = xlThin
        .ColorIndex = xlAutomatic
    End With
    With Selection.Borders(xlEdgeBottom)
        .LineStyle = xlContinuous
        .Weight = xlThin
        .ColorIndex = xlAutomatic
    End With
    With Selection.Borders(xlEdgeRight)
        .LineStyle = xlContinuous
        .Weight = xlThin
        .ColorIndex = xlAutomatic
    End With
    With Selection.Borders(xlInsideVertical)
        .LineStyle = xlContinuous
        .Weight = xlThin
        .ColorIndex = xlAutomatic
    End With
    With Selection.Borders(xlInsideHorizontal)
        .LineStyle = xlContinuous
        .Weight = xlThin
        .ColorIndex = xlAutomatic
    End With

'   Установка формата данных для первой строки (перенос по словам и выравнивание)
    Rows("1:1").Select
    Selection.NumberFormat = "@"
    With Selection
        .HorizontalAlignment = xlCenter
        .VerticalAlignment = xlTop
        .WrapText = True
        .Orientation = 0
        .AddIndent = False
        .IndentLevel = 0
        .ShrinkToFit = False
        .ReadingOrder = xlContext
        .MergeCells = False
    End With

'   Уточнение ширины столбцов
    Columns("A:A").ColumnWidth = 11.57
    Columns("B:B").ColumnWidth = 10.14

'   Уточнение высоты первой строки
    Selection.RowHeight = 25.5

'   Переход на первую ячейку для сброса выделений
    Range("A1").Select
End Sub

Разумеется, внутри кода макроса нет никаких комментариев. Я их расставил сам, для облегчения восприятия. Все остальное взято из кода макроса без изменений. Теперь попробуем разобрать, что же такое здесь понаписано.

Открытие листа Excel в FoxPro

Прежде чем приступить к «разбору полетов» собственно макроса, небольшое отступление, для того, чтобы показать как собственно открыть Excel из FoxPro. Дело в том, что последующий код перевода макроса будет, так или иначе, ссылаться на открытый лист Excel.

Новый лист Excel открывается следующим образом

* Создаем объект Excel
LOCAL loExcel
loExcel=CREATEOBJECT('Excel.Application')

* Создаем в нем новую рабочую книгу
LOCAL loBook
#DEFINE xlWBATWorksheet -4167
loBook = m.loExcel.workbooks.Add(xlWBATWorksheet)

* Создаем ссылку на новый лист в рабочей книге
LOCAL loSheet
loSheet = m.loBook.Sheets(1)

* Делаем Excel видимым
* Эту команду надо давать в самом конце формирования листа Excel
* здесь она приведена для наглядности
loExcel.Visible= .T.

Здесь сразу нужны некоторые пояснения.

Иерархия главных объектов Excel достаточно проста:

Сам объект Excel (Excel.Application) 
	Коллекция рабочих книг (WorkBooks) 
		Коллекция листов (Sheets) 
			Набор ячеек (Range, Cells, Columns, Rows)

Сам объект Excel (Excel.Application) — это некая «оболочка», которая сама по себе особого интереса не представляет. Ну, примерно как собственно среда FoxPro не имеет особого смысла без каких-то пользовательских форм или меню. Это просто «среда», где и «живут» все прочие объекты Excel

Коллекция рабочих книг (WorkBooks) — одна рабочая книга — это один файл XLS. Как правило, в одном объекте Excel открывается только один файл XLS (рабочая книга). Но, в принципе, можно открыть и несколько файлов XLS в одном объекте Excel.

Коллекция листов (Sheets) — один лист — это одна «страница» файла XLS. Или одна «сетка». При использованном выше способе создания рабочей книги будет создана рабочая книга только с одним листом. Если же вообще не указывать никаких параметров в методе Add при создании новой рабочей книги, то количество листов будет определяться настройками Excel у клиента. Пункт меню Excel с именем «Сервис» — «Параметры» — Закладка «Общие» — реквизит «Листов в новой книге»

Набор ячеек (Range, Cells, Columns, Rows) — это уже собственно ячейки листа Excel. Возможны разные способы адресации к ячейкам:

  • Range — произвольный набор ячеек, никак не связанных между собой. В частности, это может быть и одна ячейка, и строка, и столбец, и просто перечисление каких-либо ячеек
  • Cells — одна ячейка выделенного диапазона
  • Columns — один или несколько столбцов
  • Rows — одна или несколько строк

Чтобы начать заполнять лист Excel надо предварительно обязательно открыть сам объект Excel и в нем создать (или открыть) рабочую книгу.

Объект Excel создается именно командой CreateObject(), а не предварительной попыткой использовать уже существующий объект Excel через команду GetObject() не для наглядности. Именно так и следует поступать! Дело в том, что при использовании команды GetObject() неизвестно, какой именно из существующих объектов Excel будет «захвачен». Такая неопределенность рано или поздно, но «выйдет боком». Поэтому лучше создать новый объект и быть уверенным, что при этом никак не испортишь ранее открытые объекты Excel.

В приведенном выше примере я в конце концов получил ссылку на нужный мне лист Excel. Далее я буду работать именно с этой ссылкой. Однако, в принципе, вместо полной иерархии «Объект Excel — Рабочая книга — Лист — ячейка» можно работать и напрямую «Объект Excel — ячейка». Т.е. «пропустив» всю «лишнюю» иерархию «Рабочая книга — Лист».

Только следует иметь в виду, что при такой адресации тем не менее «пропущенная» иерархия будет использована. Но использована неявно. По умолчанию. В этом случае предполагается, что идет ссылка на активную рабочую книгу и активный лист. Обратите внимание на слово «активный». Это вовсе не означает «первый». Это именно «активный». Но это может быть, например, десятый лист.

Подключение механизма IntelliSens в FoxPro

Начиная с версии Visual FoxPro 7 появился механизм IntelliSens. Если у Вас младшая версия FoxPro, то данный раздел Вы можете смело пропустить. Для собственно перевода кода макроса Excel в синтаксис FoxPro то, что написано в данном разделе принципиального значения не имеет. Это просто дополнительные удобства, связанные исключительно с механизмом IntelliSens

Итак, механизм IntelliSens в частности отображает список всех свойств, методов и событий объекта в выпадающем списке, который появляется автоматически как только Вы установите точку сразу за именем объекта. Однако чтобы этот механизм сработал в программе необходимо выполнить то, что в FoxPro называется «ранее связывание». Другими словами, необходимо как-то дать понять FoxPro еще на этапе написания программного кода какой именно объект «скрывается» за выбранным именем переменной. Для этого используется специальный синтаксис в определении области видимости объекта. В данном случае, примерно так:

LOCAL loExcel as Excel.Application
loExcel=CREATEOBJECT(‘Excel.Application’)

Откуда FoxPro узнал о том, где взять список свойств, событий и методов объекта Excel.Application? А из системного реестра Windows. Точнее, конечно, в системном реестре храниться не сам список свойств, а ссылка на библиотеку, в которой эти свойства описаны. Просто в процессе установки собственно Excel в системном реестре Windows был сформирован некий идентификатор для объекта с названием Excel.Application. А уже по этому идентификатору можно определить массу информации связанную с этим объектом. В том числе и полный путь к файлу со списком свойств и методов данного объекта.

Все это, конечно, хорошо. Но ведь основная работа будет происходить не собственно с объектом Excel.Application, а с объектами, существующими внутри Excel.Application. Неужели, для того, чтобы работал механизм IntelliSens придется всегда писать полную иерархию объектов Excel начиная с самого верхнего уровня?

Нет. Не придется. Разработчики механизма IntelliSens предусмотрели возможность явного подключения списка свойств, методов и событий, как самого объекта, так и объектов, существующих внутри него.

В данном случае надо воспользоваться пунктом системного меню FoxPro с именем Tools — подпункт IntelliSens. В открывшемся окне перейдите на закладку Types и нажмите кнопку Type Libraries. Появится список тех объектов, которые зарегистрированы в системном реестре Windows. Вам следует найти в этом списке объект «Microsoft Excel 10.0 Obect Library«. Или с большим номером. Библиотека с номером 5.0 нас не интересует, поскольку она не даст нужного результата.

Ставите птичку слева от имени «Microsoft Excel 10.0 Obect Library» и нажмите кнопку «Done». Это вовзвращает Вас в окно IntelliSens Meneger. Убедитесь, что в списке объектов в этом окне появилась только что выбраная Вами дополнительная библиотека, и нажмите кнопку «Ok»

Все. Теперь механизм IntelliSens будет работать не только для объекта, непосредственно зарегистрированного в системном реестре Windows, но и для «вложенных» в него объектов. Для этого, следует переписать приведенный выше код определения объектов следующим образом.

* Создаем объект Excel
LOCAL loExcel as Excel.Application
loExcel=CREATEOBJECT('Excel.Application')

* Создаем в нем новую рабочую книгу
LOCAL loBook as Excel.Workbook
#DEFINE xlWBATWorksheet -4167
loBook = m.loExcel.workbooks.Add(xlWBATWorksheet)

* Создаем ссылку на новый лист в рабочей книге
LOCAL loSheet as Excel.Worksheet
loSheet = m.loBook.Sheets(1)

* Делаем Excel видимым
* Эту команду надо давать в самом конце формирования листа Excel
* здесь она приведена для наглядности
loExcel.Visible= .T.

Метод Select

Первое, что бросается в глаза, при просмотре кода макроса Excel, это разбросанный по всему телу макроса метод Select. Что это такое? А это просто визуализация перехода или выделения нужной ячейки. Т.е. просто визуальное отображение того факта, что Вы встали, например, на ячейку «A1».

При написании кода в FoxPro нам это совсем не нужно. Ну, действительно, зачем нам показывать пользователю, что мы встали на ячейку «A1» и сейчас начнем в ней что-то менять?

Если сравнить с формами FoxPro, то метод Select в Excel аналогичен методу SetFocus() в FoxPro. А зачем нам переводить фокус, например, в TextBox, если я могу изменить его состояние и без этого? Достаточно просто получить ссылку на нужный объект. В данном случае на ячейку Excel.

Именно так и следует поступить. Тем более, что визуализация перехода на нужные ячейки занимает довольно значительное время. Тогда первая часть макроса — «заполнение ячеек» — в синтаксисе FoxPro с учетом предыдущего кода будет выглядеть так:

* Ввод содержимого ячеек
m.loSheet.Cells(1,1).Value = "Название реквизита"
m.loSheet.Cells(1,2).Value = "Значение реквизита"
m.loSheet.Cells(2,1).Value = "Первый"
m.loSheet.Cells(2,2).Value = 1324.56
m.loSheet.Cells(3,1).Value = "Второй"
m.loSheet.Cells(3,2).Value = "9876.54"
m.loSheet.Cells(4,1).Value = "ИТОГО"

В данном случае идет обращение к каждой отдельной ячейке. Поэтому для получения ссылки я использовал метод Cell(номер строки, номер столбца).

Откуда я взял синтаксис использования Cells()? Да из HELP самого Excel. Я просто в коде макроса выделил ключевое слово «Range» и нажал клавишу F1. Далее посмотрел пример его использования и увидел такой замечательный метод Cells() и пример его использования.

Обратите внимание, что я передал число в одном случае как число (ячейка с координатами «2,2»), а в другом — как символьную строку (ячейка с координатами «3,2»). Но в обоих случаях Excel воспринял полученное значение именно как число. Это уже связано с особенностью интерпретации символьных строк самим Excel. В общем случае неочевидно, во что будет конвертировано содержимое символьной строки. Поэтому, логично указывать числа именно как числа. Впрочем, для однозначной интерпретации данных лучше делать предварительное форматирование ячеек Excel. Но об этом ниже.

О ссылках на диапазон ячеек отличный от одной ячейки будет рассказано далее.

Указание диапазона ячеек для функции

По той же самой схеме, которая описана в предыдущем разделе, формулу для расчета итога можно записать так:

* Формула расчета итога
m.loSheet.Cells(4,2).Value = "=SUM(R[-2]C:R[-1]C)"
* Или в более привычном виде
m.loSheet.Cells(4,2).Formula = "=SUM(B2:B3)"

Однако оба этих способа имеют недостатки. Начну с конца, как более очевидного

Второй способ записи неудобен тем, что в общем случае достаточно трудно перевести номер столбца в соответствующую букву. Вы можете сказать, какая буква будет соответствовать, например, 53 столбцу?

Как легко понять, первый способ использует относительные ссылки. Относительно текущей ячейки. Т.е. адрес:

R[-2]C

Следует читать как: строка (Row) на 2 выше от текущей и тот же самый, текущий, столбец (Column)

Здесь проблема в том, что не всегда легко получить именно относительные значения. Особенно, если используемый диапазон ячеек не является «сплошным». Надо исключить ряд ячеек из расчета.

Немного покопавшись в HELP и поэкспериментировав, выяснилось, что можно писать не относительные ссылки, а абсолютные

* Формула расчета итога
m.loSheet.Cells(4,2).Formula = "=SUM(R2C2:R3C2)"
* Или несколько более громоздко
m.loSheet.Cells(4,2).Formula = "=SUM("+
  m.loSheet.Cells(2,2).Address +":"+
  m.loSheet.Cells(3,2).Address +")"

Здесь первый вариант — это указание абсолютных ссылок. Второй вариант — это тоже абсолютные ссылки, но полученные не путем «расчета», а просто считанные из реквизитов нужных ячеек. Какой вариант для Вас более предпочтительный — решайте сами.

Использовать ли свойство Value или Formula в данном случае все равно. Оба свойства дадут один и тот же результат.

Обратите внимание еще на одну «тонкость». В данном случае использовано английское ключевое слово «SUM», несмотря на то, что я создал исходный макрос в русифицированной версии Excel. Т.е. если посмотреть, что же написано в самом листе Excel, то там будет стоять русское «СУММ».

Указание произвольного диапазона ячеек

Далее в коде макроса стоит установка полужирного шрифта. Здесь сложность не в самой команде установки реквизита шрифта, а в указании диапазона ячеек, для которых надо что-то изменить. Кое-что уже было написано в предыдущем разделе посвященному указанию диапазона для формулы. Здесь опишу это подробнее.

Для указания произвольного диапазона ячеек используется метод Range(). В самом общем виде он имеет примерно такой синтаксис:

m.loSheet.Range(«1:1;B:B;C2:D3»)

В данном случае указан диапазон, в который входят: все ячейки первой строки, все ячейки столбца «B», все ячейки лежащие между ячейками «C2» и «D3». Т.е. символ двоеточия выступает как фраза «от … до», а точка с запятой как фраза «… и …».

Обратите внимание, что в коде макроса Excel вместо символа точки с запятой использован символ запятой. Это не опечатка. Это отличие синтаксиса внутри Excel и при работе с самим Excel как COM-компонентом. О том, когда надо использовать «точку с запятой», а когда просто «запятую» чуть ниже.

Внутри метода RANGE недопустимо использование абсолютных ссылок вида «R1C1», как это можно сделать внутри формул. Это вызовет ошибку. Следовательно, по сути, единственным способом указания произвольного диапазона остается считывание нужных адресов. Если взять приведенный выше пример, то получается так:

m.loSheet.Range(m.loSheet.Rows(1).Address+";"+;
	m.loSheet.Columns(2).Address+";"+;
	m.loSheet.Cells(3,2).Address+":"+m.loSheet.Cells(4,3).Address)

Ну, а фрагмент кода макроса переводится в синтаксис FoxPro следующим образом:

m.loSheet.Range(m.loSheet.Rows(1).Address+";"+;
	m.loSheet.Columns(4).Address).Font.Bold = .T.

Следует заметить, что писать в одном методе RANGE() слишком уж длинных строк диапазонов не надо. Дело в том, что у команд Excel, также как и у команд FoxPro, есть ограничение по длине. В данном случае — это вероятно 1024 символа на одну команду. Если Вы хотите одной командой изменить множество разрозненных ячеек, то следует их объединить при помощи метода Union. Примерно так:

LOCAL loUnion
loUnion = m.loExcel.UNION(m.loSheet.Rows(1),m.loSheet.Rows(2))
loUnion = m.loExcel.UNION(m.loUnion,m.loSheet.Cells(3,2))
loUnion = m.loExcel.UNION(m.loUnion,m.loSheet.Cells(3,3))
loUnion = m.loExcel.UNION(m.loUnion,m.loSheet.Cells(4,2))
loUnion = m.loExcel.UNION(m.loUnion,m.loSheet.Cells(4,3))
m.loUnion.Font.Bold = .T.

Обратите внимание, что метод UNION относиться к объекту «Excel.Application» (переменная m.loExcel). Это значит, что в нем можно объединять диапазоны не просто из разных листов, но и из разных книг.

Метод UNION не может иметь меньше двух параметров. Однако нельзя одной командой указать больше 30 параметров. Впрочем, как видно из примера, можно наращивать уже объединенные ячейки. Т.е. в качестве первого параметра указать ранее объединенный через UNION диапазон ячеек.

Использование метода UNION — это еще один способ указания произвольного диапазона

Когда использовать «запятую», а когда «точку с запятой

При переводе кода макроса Excel в синтаксис FoxPro иногда приходится заменять символ «запятой» на символ «точки с запятой» и наоборот. С чем это связано, и когда это необходимо делать?

Это связано с особенностью разделения параметров в синтаксисе Visual Basic и в синтаксисе FoxPro. Чтобы не залезать глубоко в «дебри» мудреных определений просто запомните общее правило:

Если необходимо отделить друг от друга элементы одного списка, то в синтаксисе FoxPro следует использовать символ «точки с запятой». А если друг от друга отделяются «параметры», то следует использовать символ «запятой».

Чтобы было понятно о чем речь, возьмем ранее рассмотренный пример выделения диапазона ячеек. В макросе Excel это записано так:

Range(«1:1,4:4»).Select

Здесь, по смыслу, внутри Range() просто перечислены элементы одного списка. Если «перевести» это на русский язык, то можно прочитать это так: выделить первую и четвертую строку

Поскольку речь идет именно о перечислении, а не о параметрах, то в синтаксисе FoxPro следует заменить символ «запятой» на символ «точки с запятой». Примерно так:

m.loSheet.Range(«1:1;4:4»).Select

К сожалению, в использованном в качестве примера коде макроса нет функций, которые бы использовали диапазоны как параметры. Поэтому приведу пример функции ЕСЛИ() никакого отношения к разбираемому коду макроса не имеющую.

.ActiveCell.FormulaR1C1 = ‘=IF(RC[-1]>0;RC[-1];»»)’

В данном случае, эта формула «переводится» так. Если значение ячейки в текущей строке, но на столбец ранее больше нуля, то отобразить значений этой ячейки. В противном случае — ничего не отображать.

Как видите, в коде макроса использован символ «точки с запятой». Но в данном случае, разделенные величины выступают как параметры. Это явно не перечисление. Значит, в синтаксисе FoxPro следует вместо символа «точки с запятой» использовать символ «запятой».

m.loSheet.Cells(2,3).Value = ‘=IF(RC[-1]>0,RC[-1],»»)’

Указание формата ячеек

Далее в коде макроса стоит указание формата для всего второго столбца. В переводе в синтаксис FoxPro это выглядит так:

m.loSheet.Columns(2).NumberFormat = «#,##0.00»

Обратите внимание, что хотя числовой формат был задан на весь второй столбец, но тем не менее содержимое заголовка столбца (первой строки) как было текстом, так текстом и осталось.

В данном случае символ запятой и точки — это не есть реальные символы-разделители. Их назначение аналогично назначению тех же символов при задании маски ввод «InputMask» в FoxPro.

По умолчанию, все ячейки листа Excel имеют формат «General». Это некий универсальный формат, который сам, автоматически, предпринимает попытку конвертировать полученные данные в тот формат, который он считает наиболее правильным. Это не всегда хорошо.

Например, если Вы выводите в Excel банковский расчетный счет (это 20 цифр), то Excel автоматически конвертирует полученное значение в число. Но, поскольку точность вычисления Excel до 15 значащих цифр, то произойдет округление и последующее изменение формата отображения уже не сможет исправить эту ошибку.

В подобных случаях надо до начала вывода в Excel установить формат ячеек — текстовый

m.loSheet.Columns(1).NumberFormat = «@»

Установка условного формата для числовых данных второго столбца

Далее по коду макроса идет установка условного формата. Но чтобы понять, что там написано, и как это перевести в FoxPro следует сделать ряд пояснений

Константы Excel

В теле макроса встречаются странные значения, которые начинаются с символов «xl». В данном случае — это xlCellValue и xlLess. Но и дальше по коду макроса встречаются аналогичные значения. Это именно значения, поскольку, судя по коду, они присваиваются неким параметрам. Что это такое?

Это константы. Т.е. это некоторые значения, которые были определены в момент открытия Excel. Их отличительным признаком как раз и является то, что они начинаются с символов «xl» и из кода макроса следует, что это некоторые ранее определенные значения.

Определить, чему же равны эти константы можно там же, в редакторе «Microsoft Visula Basic», где Вы и просматриваете код макроса Excel. Для этого надо открыть «Object Browser». Пункт меню «View» — подпункт «Object Browser». Далее в пустом окошке слева от кнопки с иконкой бинокля ввести имя искомой константы и нажать кнопку с иконкой бинокля (или клавишу Enter). В результате поиска в самом низу окна «Object Browser» будет отображено значение искомой константы.

В синтаксисе FoxPro константы записываются через директиву #DEFINE следующим образом:

#DEFINE xlCellValue 1
#DEFINE xlLess 6

Именованные параметры функций Excel

В коде макроса, для установки условного формата используется функция ADD с несколькими именованными параметрами. Как это перевести в синтаксис FoxPro, ведь в нем нет такого понятия как «именованный параметр»

Именованный параметр — это передача параметров в функцию не обязательно в порядке их определения, но при этом значению параметра предшествует его имя. В этом случае принимающая функция проанализирует имя параметра и поймет, к чему именно следует отнести полученное значение.

Повторю еще раз. Такого в FoxPro нет. Т.е. реализовать-то это не проблема. Просто этого нет «штатно». На уровне самой среды FoxPro.

А вот здесь как раз избыточность макроса Excel очень кстати. Дело в том, что в подобных случаях, макрорекодер Excel запишет вообще все параметры, какие есть у данной функции или метода и расположит их в том порядке, в котором они идут в самой функции.

В синтаксисе FoxPro параметры должны идти в том порядке, в котором они определены в функции и отделяться друг от друга запятыми. В макросе Excel они также будут идти в том порядке, в котором они определены в функции, но отделены друг от друга пробелом и каждому значению параметра предшествует его имя.

Тогда все очень просто. В FoxPro установка условного форматирования примет вид

#DEFINE xlCellValue 1
#DEFINE xlLess 6
LOCAL loUnion, loFormatCondition
loUnion = m.loExcel.Union(m.loSheet.Cells(2,2),m.loSheet.Cells(3,2))
loUnion = m.loExcel.Union(m.loUnion,m.loSheet.Cells(4,2))
m.loUnion.FormatConditions.Delete
loFormatCondition = m.loUnion.FormatConditions.Add(xlCellValue,xlLess,2000)
m.loFormatCondition.Interior.ColorIndex = 3

В данном случае, все параметры метода Add() обязательны. Т.е. нельзя не задать какой-либо из параметров. Однако во многих функциях часть параметров задавать не обязательно. Это означает либо что данный параметр остается неизменным, либо принимает некоторое значение по умолчанию. В этом случае в синтаксисе FoxPro можно просто ничего не указывать, но обязательно поставить запятую, чтобы нужный нам параметр оказался на соответствующем месте.

Рисование рамки вокруг всех данных

В переводе кода рисования рамки ничего нового нет. Разве что, здесь просто не нужно указывать ряд команд. Например, зачем указывать, что нет диагональных линий, если их и так нет? А в остальном все то же самое, что было описано ранее:

#DEFINE xlThin 2
#DEFINE xlDiagonalDown 5
#DEFINE xlDiagonalUp 6
#DEFINE xlEdgeLeft 7
#DEFINE xlEdgeTop 8
#DEFINE xlEdgeBottom 9
#DEFINE xlEdgeRight 10
#DEFINE xlInsideVertical 11
#DEFINE xlInsideHorizontal 12

LOCAL loRange
loRange = m.loSheet.Range(m.loSheet.Cells(1,1).Address+":"+m.loSheet.Cells(4,2).Address)
loRange.Borders(xlEdgeLeft).Weight = xlThin
loRange.Borders(xlEdgeTop).Weight = xlThin
loRange.Borders(xlEdgeBottom).Weight = xlThin
loRange.Borders(xlEdgeRight).Weight = xlThin
loRange.Borders(xlInsideVertical).Weight = xlThin
loRange.Borders(xlInsideHorizontal).Weight = xlThin

Как видите, большая часть кода просто не вошла в итоговый «перевод». В этом нет необходимости. В данном случае нас вполне устраивает стиль и цвет линий по умолчанию. Т.е. сплошная линия черного цвета. Нет смысла менять эти значения. Достаточно только указания толщины (веса) линии

Перенос слов, выравнивание, ширина столбца и высота строки

Собственно, оставшийся код Вы уже можете перевести самостоятельно. Поэтому я приведу его уже безо всяких пояснений

#DEFINE xlCenter -4108
#DEFINE xlTop -4160

m.loSheet.Rows(1).NumberFormat = "@"
m.loSheet.Rows(1).HorizontalAlignment = xlCenter
m.loSheet.Rows(1).VerticalAlignment = xlTop
m.loSheet.Rows(1).WrapText = .T.
m.loSheet.Rows(1).RowHeight = 25.5

m.loSheet.Columns(1).ColumnWidth = 11.57
m.loSheet.Columns(2).ColumnWidth = 10.14
  • Remove From My Forums
  • Вопрос

  • I am using Visual FoxPro 6.0 version.  I need an excel file just view in Visual FoxPro 6.0 form… Please send the code and proceedures….

Ответы

  • I’d never do that myself and show it in Excel’s own application window. However if you’d do anyway:

    Code Snippet

    lcXLSFile = getFile(‘XLS’)

    PUBLIC oForm
    oForm = createobject(‘myExcelForm’,m.lcXLSFile)
    oForm.show()

    define class myExcelForm as form
      top = 0
      left = 0
      height = 450
      width = 750
      docreate = .t.
      caption = «HTML Excel sample»

      * This is IE control — you’d use webbrowser4 from gallery instead
      * just because it already has some checks, extra pem. ie: wouldn’t need readystate part
      * for the sake of keeping code short here I directly use olecontrol itself
      add object htmlviewer as olecontrol with ;
        top = 0, ;
        left = 0, ;
        height = 450, ;
        width = 750, ;
        visible = .t., ;
        name = «HTMLViewer», ;
        oleclass = ‘Shell.Explorer’

      procedure init
        lparameters tcXLSFile
        with thisform.htmlviewer
          .Navigate2(‘file://’+m.tcXLSFile)
          do while .ReadyState # 4 && Wait for ready state
          enddo
        endwith
      endproc
    enddefine

    Instead of web browser you might directly use an place editing window too. It’s however is much worse and here is why:

    Code Snippet

    lcXLS = Getfile(‘XLS’)
    Set Textmerge To Memvar myVar Noshow
    Set Textmerge On
    DEFINE CLASS oleExcelObject as OLEControl
     OleClass =»Excel.Sheet»  && Server name
     OleTypeAllowed = 0      && Linked
     DocumentFile = «<<m.lcXLS>>» && This file should exist
    ENDDEFINE
    Set Textmerge To
    Set Textmerge Off
    lcTempClass = Sys(2015)+’.prg’
    Strtofile(myVar, lcTempClass)
    Compile (lcTempClass)

    PUBLIC oForm
    oform = Createobject(«Form»)
    oForm.Show()

    With oform
      .Height = 420
      .Width = 620
      .Newobject(«ExcelObject»,»oleExcelObject»,lcTempClass)  && Add OLE object
      With .ExcelObject
        .Left = 5
        .Top = 5
        .Width = .Parent.Width — 10
        .Height = .Parent.Height — 10
        .Visible = .T.
      Endwith
    Endwith
    oform.Show
    Read Events
    Clear Class ‘oleExcelObject’
    Erase (Juststem(m.lcTempClass)+’.*’)

  • In addition to Cetin’s reply there is another interesting idea (in this sample I use Word, though)

    DECLARE SetParent IN user32 integer hWndChild, integer hWndParent    
    
      DECLARE integer SetWindowPos IN User32 ;    
        	integer Wnd_handler, integer Window_Order, ;    
        		integer X1, integer Y1, integer X2, integer Y2, integer wFlags    
    
      DECLARE LONG FindWindow IN Win32API ;    
            STRING lpClassName;    
            ,STRING lpWindowName    
    
        loWord = CREATEOBJECT( 'WORD.APPLICATION')   
        lcFile = GETFILE('doc') 
        loDoc=m.loWord.Documents.Add(m.lcFile)   
    
        _PP=lodoc.name +" - "+loword.CAPTION  
    
        word_hwnd=FindWindow(NULL,_pp)   
        SetParent( word_hwnd, thisform.HWnd)  
        setWindowPos( word_hwnd,0,0,INT(THISFORM.Height/2),THISFORM.Width-1,THISFORM.HEIGHT-1,0)   
        loword.ActiveWindow.ActivePane.View.Zoom.PageFit = 1  
    
      loword.VISIBLE=.T.

У меня данный способ заработал.  Вы сами не знаете какой именно файл

Предлагаю вам создать в Visual Foxpro 9 новый файл данных, занести туда пару строк и продемонстрировать работу вашего способа.

Если у вас нет Visual Foxpro 9 — то могу сам вам создать данный файл данных (если вы согласны скачать с темы «неизвестное» вложение), а вы на нём продемонстрируете, как это работает на практике.

Скриншотами с Excel.

Складывается ощущения, что вы считаете себя самым умным, а остальные ****

У вас складывается неверное ощущение.

Я просто привык проверять ответы на задачи, с которыми я сталкивался раньше на практике, и если они неверны — информировать об этом собеседника. Считайте это дружеской помощью, а не попыткой троллить.

Если я, к примеру, буду давать неверные ответы по настройкам KIS 2016, а в ответ на поправки форумчан, аргументировать, показать это я не могу, т.к. у меня нет на компьютере KIS 2016 и я им вообще не пользуюсь, но это всё равно должно быть так, то вот это уже будет троллингом.

Вероятно нужно промолчать по вашим сообщениям, если это как то задевает вашу самооценку. Не буду даже снижать вам репутацию за неверные ответы, как это принято на форумах.

Как было правильно замечено:

Какая вам разница — признаю я ваш вариант истинным или нет


Изменено 11 декабря, 2015 пользователем Turkoman

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
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
 #Define xlCenter          -4108            
  #Define xlSolid               1  
  #Define xlEdgeLeft            7  
  #Define xlEdgeTop             8  
  #Define xlEdgeBottom          9  
  #Define xlEdgeRight          10  
  #Define xlInsideVertical     11  
  #Define xlInsideHorizontal   12  
  #Define xlThin                2  
  #Define xlThick               4  
  #Define xlMedium          -4138  
  #Define xlDouble          -4119  
    
  Local lcPath, loExcel, lnRow  
    
  loExcel = Createobject("Excel.Application")  
    
  With loExcel  
    .Visible = .T.  
    .WorkBooks.Add  
 **.ActiveWindow.DisplayZeros = .F.  
 * Устанавлиаем ширину столбцов  
    .Columns[1].ColumnWidth = 5  
    .Columns[2].ColumnWidth = 40  
    .Columns[3].ColumnWidth = 10.71  
    .Columns[4].ColumnWidth = 15  
    .Columns[5].ColumnWidth = 15  
    .Columns[6].ColumnWidth = 15  
    .Columns[7].ColumnWidth = 15  
    .Columns[8].ColumnWidth = 15  
    .Columns[9].ColumnWidth = 15  
    
    
    
    
 * Заголовок  
    .cells(1,3).Font.Size = 13  
    .cells(1,3).Font.Bold = .T.  
    .cells(1,3).Value = 'Накопительная ведомость данных путевых листов по автомобилям'  
    .cells(2,5).Font.Size = 11                  
    .cells(2,5).Font.Bold = .F.  
      
    
    .Range("A7:I7").Select  
    .ActiveWindow.FreezePanes = .T.  
    With .Selection  
        .RowHeight = 18                         
        .Font.Size = 10  
        .Font.Bold = .T.  
    Endwith  
    .cells(5,1).Value = '№ пп'  
    .cells(5,2).Value = 'Наименование автомобиля, номер и дата путевого листа'  
    .cells(5,3).Value = 'Единица измерения'  
    .cells(5,4).Value = 'Остаток на начало отчетного периода'  
    .cells(5,5).Value = 'Поступило'  
    .cells(5,6).Value = 'Расход '  
    .cells(5,7).Value = 'Остаток на конец отчетного периода'  
    .cells(5,8).Value = 'Показания спидометра на'  
    .cells(6,8).Value = 'начало отчетного периода'  
    .cells(6,9).Value = 'конец отчетного периода'  
    
 *редактируем ячейки для дальнейшего использования  
    .Range("A5:A6").Select  
    With .Selection  
        .MergeCells = .T.  
        .HorizontalAlignment = xlCenter  
        .VerticalAlignment = xlCenter  
        .WrapText = .T.  
        .Orientation = 0  
        .AddIndent = .F.  
        .IndentLevel = 0  
        .ShrinkToFit = .F.  
        .ReadingOrder = -5002   &&xlContext  
    Endwith  
    .Range("B5:B6").Select  
    With .Selection  
        .MergeCells = .T.  
        .HorizontalAlignment = xlCenter  
        .VerticalAlignment = xlCenter  
        .WrapText = .T.  
        .Orientation = 0  
        .AddIndent = .F.  
        .IndentLevel = 0  
        .ShrinkToFit = .F.  
        .ReadingOrder = -5002  
    Endwith  
    .Range("C5:C6").Select  
    With .Selection  
        .MergeCells = .T.  
        .HorizontalAlignment = xlCenter  
        .VerticalAlignment = xlCenter  
        .WrapText = .T.  
        .Orientation = 0  
        .AddIndent = .F.  
        .IndentLevel = 0  
        .ShrinkToFit = .F.  
        .ReadingOrder = -5002  
    Endwith  
    .Range("D56").Select  
    With .Selection  
        .MergeCells = .T.  
        .HorizontalAlignment = xlCenter  
        .VerticalAlignment = xlCenter  
        .WrapText = .T.  
        .Orientation = 0  
        .AddIndent = .F.  
        .IndentLevel = 0  
        .ShrinkToFit = .F.  
        .ReadingOrder = -5002  
    Endwith  
    .Range("E5:E6").Select  
    With .Selection  
        .MergeCells = .T.  
        .HorizontalAlignment = xlCenter  
        .VerticalAlignment = xlCenter  
    Endwith  
    .Range("F5:F6").Select  
    With .Selection  
        .MergeCells = .T.  
        .HorizontalAlignment = xlCenter  
        .VerticalAlignment = xlCenter  
    Endwith  
    .Range("G5:G6").Select  
    With .Selection  
        .MergeCells = .T.  
        .HorizontalAlignment = xlCenter  
        .VerticalAlignment = xlCenter  
        .WrapText = .T.  
        .Orientation = 0  
        .AddIndent = .F.  
        .IndentLevel = 0  
        .ShrinkToFit = .F.  
        .ReadingOrder = -5002  
    Endwith  
    .Range("H5:I5").Select  
    With .Selection  
        .MergeCells = .T.  
        .HorizontalAlignment = xlCenter  
        .VerticalAlignment = xlCenter  
    Endwith  
    .Range("H6:H6").Select  
    With .Selection  
        .MergeCells = .T.  
        .HorizontalAlignment = xlCenter  
        .VerticalAlignment = xlCenter  
        .WrapText = .T.  
        .Orientation = 0  
        .AddIndent = .F.  
        .IndentLevel = 0  
        .ShrinkToFit = .F.  
        .ReadingOrder = -5002  
    Endwith  
    .Range("I6:I6").Select  
    With .Selection  
        .MergeCells = .T.  
        .HorizontalAlignment = xlCenter  
        .VerticalAlignment = xlCenter  
        .WrapText = .T.  
        .Orientation = 0  
        .AddIndent = .F.  
        .IndentLevel = 0  
        .ShrinkToFit = .F.  
        .ReadingOrder = -5002  
    Endwith  
    
    .Range("A5:I6").Select  
    With .Selection  
        .BorderS(xlEdgeLeft).Weight = xlMedium  
        .BorderS(xlEdgeTop).Weight = xlMedium  
        .BorderS(xlEdgeBottom).Weight = xlMedium  
        .BorderS(xlEdgeRight).Weight = xlMedium  
        .BorderS(xlInsideVertical).Weight = xlThin  
        .BorderS(xlInsideHorizontal).Weight = xlThin  
        .HorizontalAlignment = xlCenter  
        .VerticalAlignment = xlCenter  
    Endwith  
    .Rows("6:6").RowHeight = 45  
    .cells(7,1).NumberFormat = "@"  
    .cells(7,1).Value = "1"  
    .cells(7,2).NumberFormat = "@"  
    .cells(7,2).Value = "2"  
    .cells(7,3).NumberFormat = "@"  
    .cells(7,3).Value = "3"  
    .cells(7,4).NumberFormat = "@"  
    .cells(7,4).Value = "4"  
    .cells(7,5).NumberFormat = "@"  
    .cells(7,5).Value = "5"  
    .cells(7,6).NumberFormat = "@"  
    .cells(7,6).Value = "6"  
    .cells(7,7).NumberFormat = "@"  
    .cells(7,7).Value = "7"  
    .cells(7,8).NumberFormat = "@"  
    .cells(7,8).Value = "8"  
    .cells(7,9).NumberFormat = "@"  
    .cells(7,9).Value = "9"  
    *делаем сквозную строку  
     With .ActiveSheet.PageSetup  
          .PrintTitleRows = "$7:$7"  
          .PrintTitleColumns = ""  
      EndWith  
    
    .Range("A7:I7").Select  
    With .Selection  
        .BorderS(xlEdgeLeft).Weight = xlMedium  
        .BorderS(xlEdgeTop).Weight = xlMedium  
        .BorderS(xlEdgeBottom).Weight = xlMedium  
        .BorderS(xlEdgeRight).Weight = xlMedium  
        .BorderS(xlInsideVertical).Weight = xlThin  
        .BorderS(xlInsideHorizontal).Weight = xlThin  
        .HorizontalAlignment = xlCenter  
        .VerticalAlignment = xlCenter  
    Endwith  
    
    lnRow = 7  
 *тут заполняем таблицу своими данными  
    
  .Range(.cells(8,1),.cells(lnRow, 9)).Select  
  With .Selection  
    .BorderS(xlEdgeLeft).Weight = xlMedium  
    .BorderS(xlEdgeTop).Weight = xlMedium  
    .BorderS(xlEdgeBottom).Weight = xlMedium  
    .BorderS(xlEdgeRight).Weight = xlMedium  
    .BorderS(xlInsideVertical).Weight = xlThin  
    .BorderS(xlInsideHorizontal).Weight = xlThin  
    .HorizontalAlignment = xlCenter  
    .VerticalAlignment = xlCenter  
  Endwith  
    
    
    lnRow = lnRow + 2  
    .cells(lnRow,2).NumberFormat = "@"  
    .cells(lnRow,2).Value = "Отчет проверил _______________________________________________________________________"  
  Endwith  
    
    
  Messagebox ('Данные выгружены в программу Excel',0+48,;  
    'Сообщение программы')

Like this post? Please share to your friends:
  • Foxpdf word to pdf converter
  • Foxpdf excel to pdf converter
  • Foxit reader экспорт в word
  • Foxit reader как изменить на word
  • Foxit reader microsoft word