Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Microsoft Office и VBA программирование > Microsoft Office Excel
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 02.10.2012, 00:48   #1
tvitaly1
Заблокирован
 
Регистрация: 02.10.2012
Сообщений: 28
По умолчанию модель кодирования переменных в Excel VBA

здравствуйте, помогите пожалуйста.

Делаю модель кодирование переменных в Excel на VBA. Демонстрируется как храняться переменные типа Byte, Integer, long, Single, Currency и др. в битах, с ними все получилось.Идет преобразование из 10-чной ситемы в двоичную, и обратно. С переменной Date ничего не получается не могу понять как кодируется. Не знаете как?
Посмотрел как кодируется в микросхеме, ничего не получается. Может биты правильно не передаются через файл? Но ведь с Single, Currency все передалось правильно, вот мои функции.

Код:
Public Function bit(число, вес)
 n = число And вес
 If n = вес Then
   bit = 1
 Else
   bit = 0
 End If

End Function

Public Function bitLng(число, вес)

If вес = 2147483648# Then
 'Преобразование знакового бита
 '(получить значение старшего бита
 'с весом 2147483648 функцией And невозможно)
 If число < 0 Then
  bitLng = 1
 Else
  bitLng = 0
 End If

Else
  'преобразование битов числа
  bitLng = bit(число, вес)

End If
End Function

Public Function bitF(число As Boolean, вес)

 'преобразование битов числа
  bitF = bit(число, вес)

End Function


Public Function Число(Знак, Характеристика, Мантиса)
If (Характеристика > 0) And (Характеристика < 255) Or (Характеристика = 0) And (Мантиса <> 0) Then
  Число = (1 + Мантиса) * 2 ^ (Характеристика - 127) * (1 - Знак * 2)
ElseIf Характеристика = 255 Then
  If Мантиса = 0 Then
   Число = "Бесконечность"
  Else
   Число = "Не число"
  End If
Else
  Число = 0
End If

End Function


'Функции для преобразования через файл

Public Function SNGInLNG(число)
 Dim C1 As Long, f As String

 f = CurDir
 If Mid(f, Len(f)) <> "\" Then
 f = f + "\"
 End If
 f = f + "SNGInLNG$$$"

 If Dir(f) <> "" Then
 Kill f
 End If
 Open f For Random Access Read Write As 1 Len = 4
 'передаем в файл 4-х байтную переменную
 Put #1, 1, CSng(число)
 'cчитываем биты переменной Single в 4-х байтную переменную Long
 Get #1, 1, C1
 Close #1
 Kill f


 SNGInLNG = C1

End Function


Public Function CURinLNG(число, НомерТетрады, тип As String)
 Dim C1 As Long, f As String

 тип = Format(тип, "<")
 If тип <> "cur" And тип <> "date" Then
  MsgBox "Тип функции должен иметь значения ""cur"" или ""date"" "
 exit function 
End If

 f = CurDir
 If Mid(f, Len(f)) <> "\" Then
 f = f + "\"
 End If
 f = f + "CURinLNG$$$"

 If Dir(f) <> "" Then
 Kill f
 End If

 Open f For Random Access Write As 1 Len = 8
 'передаем в файл 8-ми байтную переменную
 If тип = "cur" Then
  Put #1, 1, CCur(число)
 Else
  Put #1, 1, CDate(число)
 End If
 Close #1

 Open f For Random Access Read As 1 Len = 4
 'cчитываем биты переменной Currency в 4-х байтную переменную Long
 'из верхней или нижней тетрады
  Get #1, НомерТетрады, C1
 Close #1


 Kill f

 CURinLNG = C1

End Function

Последний раз редактировалось tvitaly1; 02.10.2012 в 01:07.
tvitaly1 вне форума Ответить с цитированием
Старый 02.10.2012, 01:52   #2
EducatedFool
Программист VBA
СуперМодератор
 
Аватар для EducatedFool
 
Регистрация: 13.07.2008
Сообщений: 6,856
По умолчанию

Цитата:
С переменной Date ничего не получается
А чем, по сути, она отличается от переменной Single?
Такое же точно число
Преобразовывайте в число путем x=csng(now), и в переменной x получите значение типа 41184,16
Обратно преобразовать можно так: d=cdate(x)
EducatedFool вне форума Ответить с цитированием
Старый 02.10.2012, 10:18   #3
tvitaly1
Заблокирован
 
Регистрация: 02.10.2012
Сообщений: 28
По умолчанию

Цитата:
Сообщение от EducatedFool Посмотреть сообщение
А чем, по сути, она отличается от переменной Single?
Такое же точно число
Преобразовывайте в число путем x=csng(now), и в переменной x получите значение типа 41184,16
Обратно преобразовать можно так: d=cdate(x)
Отличается, и по количеству байт, и по способу кодирования.
Мне не нужно преобразовывать из типа в тип. Я получаю коды битов, а затем преобразую из двоичной системы десятичную. С Singl получил моим способом и мантису и характеристику в двоичной системе, а затем преобразовал все в десятичное число из мантисы и характеристики.
Currency во преки утверждениям в литературе, не кодируется десятичными цифрами в двоичной системе. Из исходного десятичного числа каким-то образом получают число больше на 10000, за затем целая часть переводится в двоичную систему счисления.
Как кодируется date, т.е., как в ней кодируются секунды, минуты, числа и т.п., понять не могу.
tvitaly1 вне форума Ответить с цитированием
Старый 02.10.2012, 10:35   #4
DiemonStar
Старожил
 
Регистрация: 08.02.2012
Сообщений: 2,173
По умолчанию

Цитата:
Date variables are stored as IEEE 64-bit (8-byte) floating-point numbers that represent dates ranging from 1 January 100 to 31 December 9999 and times from 0:00:00 to 23:59:59. Any recognizable literal date values can be assigned to Date variables. Date literals must be enclosed within number signs (#), for example
(c) Microsoft, Справка VBA

поэтому дата содержится не в single, а в double переменной, где целая часть числа = дате, а дробная часть = времени (в долях суток: час равен 1/24, минута равна 1/(24*60) и т.д.). За начало отсчёта принято 00.01.1900 = 0, но, фактически, все значения от 0 до 1 указывают, что содержится только время без даты, а начало отсчёта именно даты (совместно со временем) начинается от 1 = 01.01.1900

з.ы. можете проверить, внося значения в ячейки excel которая отформатирована как дата.
Правильно поставленная задача - три четверти решения.

Последний раз редактировалось DiemonStar; 02.10.2012 в 10:44.
DiemonStar вне форума Ответить с цитированием
Старый 02.10.2012, 11:10   #5
tvitaly1
Заблокирован
 
Регистрация: 02.10.2012
Сообщений: 28
По умолчанию

Цитата:
Сообщение от DiemonStar Посмотреть сообщение
(c) Microsoft, Справка VBA

поэтому дата содержится не в single, а в double переменной, где целая часть числа = дате, а дробная часть = времени (в долях суток: час равен 1/24, минута равна 1/(24*60) и т.д.). За начало отсчёта принято 00.01.1900 = 0, но, фактически, все значения от 0 до 1 указывают, что содержится только время без даты, а начало отсчёта именно даты (совместно со временем) начинается от 1 = 01.01.1900

з.ы. можете проверить, внося значения в ячейки excel которая отформатирована как дата.
Спасибо, DiemonStar, уже начинаю что то понимать.
Наверно, это исходный формат Double. надо будет проверить.

Последний раз редактировалось tvitaly1; 02.10.2012 в 11:56.
tvitaly1 вне форума Ответить с цитированием
Старый 02.10.2012, 12:10   #6
Казанский
Старожил
 
Аватар для Казанский
 
Регистрация: 31.12.2010
Сообщений: 2,133
По умолчанию

> в каких битах мантисса, в каких характеристика?

Структура чисел Double и Single:
http://en.wikipedia.org/wiki/Double-...g-point_format
http://en.wikipedia.org/wiki/Single-...g-point_format

Для того, чтобы скопировать содержимое одной переменной в другую, совсем необязательно записывать в файл и считывать из файла
Можно использовать WinAPI функцию RtlMoveMemory или оператор LSet (применительно к переменным пользовательского типа).
exceleved@yandex.ru Яндекс.Деньги: 410011500007619
Казанский вне форума Ответить с цитированием
Старый 02.10.2012, 12:57   #7
tvitaly1
Заблокирован
 
Регистрация: 02.10.2012
Сообщений: 28
По умолчанию

Цитата:
Сообщение от Казанский Посмотреть сообщение
> в каких битах мантисса, в каких характеристика?

Структура чисел Double и Single:
http://en.wikipedia.org/wiki/Double-...g-point_format
http://en.wikipedia.org/wiki/Single-...g-point_format

Для того, чтобы скопировать содержимое одной переменной в другую, совсем необязательно записывать в файл и считывать из файла
Можно использовать WinAPI функцию RtlMoveMemory или оператор LSet (применительно к переменным пользовательского типа).
За ссылку спасибо большое
http://en.wikipedia.org/wiki/Double-...g-point_format

C LSet, простите, не могу разобраться. Подскажите пожалуйста, как переслать биты из переменной single в переменную integer при помощи LSet?
tvitaly1 вне форума Ответить с цитированием
Старый 02.10.2012, 13:13   #8
DiemonStar
Старожил
 
Регистрация: 08.02.2012
Сообщений: 2,173
По умолчанию

Цитата:
Single (single-precision floating-point) variables are stored as IEEE 32-bit (4-byte) floating-point number
Цитата:
Integer variables are stored as 16-bit (2-byte) numbers
Не находите, что сложно сохранить в двух байтах четыре? тут как-минимум Long нужен.

И вообще, учитесь читать справку - там есть 80% ответов на все вопросы.

Вот так, например:
Код:
Type T1
  A As Single
End Type

Type T2
  A As Long
End Type

Sub Test()
 Dim A As T1, B As T2
  A.A = 1.1
 LSet B = A
 MsgBox B.A
End Sub
Правильно поставленная задача - три четверти решения.

Последний раз редактировалось DiemonStar; 02.10.2012 в 13:20.
DiemonStar вне форума Ответить с цитированием
Старый 02.10.2012, 13:18   #9
Казанский
Старожил
 
Аватар для Казанский
 
Регистрация: 31.12.2010
Сообщений: 2,133
По умолчанию

За одного Single два Integer дают Поэтому так:
Код:
Type tSng
    s As Single
End Type

Type tInt2
    i(1 To 2) As Integer
End Type

Sub bb()
Dim a As tSng, b As tInt2
a.s = Timer     'кладем число в Single
LSet b = a      'переносим в массив Integer
Debug.Print b.i(1), b.i(2)
End Sub
exceleved@yandex.ru Яндекс.Деньги: 410011500007619
Казанский вне форума Ответить с цитированием
Старый 02.10.2012, 13:24   #10
Казанский
Старожил
 
Аватар для Казанский
 
Регистрация: 31.12.2010
Сообщений: 2,133
По умолчанию

То же самое с API функцией
Код:
Declare Sub RtlMoveMemory Lib "kernel32" (Dst As Any, Src As Any, ByVal Length As Long)

Sub nn()
Dim s As Single, i(1 To 2) As Integer
s = Timer
RtlMoveMemory i(1), s, 4& 'переслать на адрес первого эл-та массива с адреса переменной s 4 байта
Debug.Print i(1), i(2)
End Sub
exceleved@yandex.ru Яндекс.Деньги: 410011500007619
Казанский вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
VBA Word,VBA Excel решить 2 задачи fafolo4ka Фриланс 6 05.03.2012 01:15
Обнуление глобальных переменных в VBA Arkasha69 Microsoft Office Excel 1 06.09.2010 15:06
vba+excel Анна Рожкова Microsoft Office Excel 18 28.05.2010 21:41
сезонная адаптивная модель в VBA Kudoh Microsoft Office Excel 0 18.06.2009 19:31
Как запретить запуск программы на VBA Excel 2003 в Excel 2007 kovalevskivf Microsoft Office Excel 2 15.05.2009 16:47