Ru-Board.club
← Вернуться в раздел «Прикладное программирование»

» Excel VBA (часть 3)

Автор: KF121
Дата сообщения: 12.07.2011 08:18
вот парочка полезный функций, которые всегда пригодятся.


Код: '******************************************************
'Procedure : SwitchNumToAlpha
'Function : Given Number equivalent Alphabet
'Requires : Number
'Returns : Alphabet
'Created By : Jay Sarsonas 6/21/2010
'******************************************************
Public Function SwitchNumberToAlphabet(inAlphaNumeric As Long) As String
Dim High
Dim Low

High = inAlphaNumeric \ 26
Low = inAlphaNumeric Mod 26

SwitchNumberToAlphabet = ""

If Low = 0 Then
Low = 26
High = High - 1
End If

If (High > 0) Then
SwitchNumberToAlphabet = Chr(Asc("A") + High - 1)
End If

SwitchNumberToAlphabet = SwitchNumberToAlphabet & Chr(Asc("A") + Low - 1)
End Function

'******************************************************
'Procedure: GetMaxDataRows
'Function: Identifies Max Record Rows given
' Worksheet and Range
'Requires: Worksheet and Range
'Returns: None
'Created by Jay Sarsonas 4/19/2010
'******************************************************
Public Function GetMaxDataRows(xSheetName As String, xRange As String) As Long
'Identify Max Used Rows
With Worksheets(xSheetName)
GetMaxDataRows = .Range(xRange & 65534).End(xlUp).Row
End With
End Function

'******************************************************
'Procedure: GetMaxDataColumns
'Function: Identifies Max Record Columns given
' Worksheet and Range
'Requires: Worksheet and Range
'Returns: None
'Created by Jay Sarsonas 8/23/2010
'******************************************************
Public Function GetMaxDataColumns(xSheetName As String, xRange As String) As Long
'Identify Max Used Rows
With Worksheets(xSheetName)
GetMaxDataColumns = .Range("IU1").End(xlToLeft).Column
End With
End Function
Автор: SAS888
Дата сообщения: 12.07.2011 08:19
KorolCOOL

Цитата:
Я знаю один способ...

А чем Вас не устраивает мой пример? Это другой способ. Который не требует буквенного определения конечного столбца.
Автор: KF121
Дата сообщения: 12.07.2011 08:22
куда делось мое сообщение? я его почему-то не вижу
Автор: asbo
Дата сообщения: 12.07.2011 09:03
KF121

Цитата:
куда делось мое сообщение? я его почему-то не вижу

Если предыдущее, то я вижу
Автор: KF121
Дата сообщения: 12.07.2011 09:05
теперь и я, видать глюк какой-то был.
Автор: KorolCOOL
Дата сообщения: 12.07.2011 10:22
SAS888 спасибо помогло.
Автор: smirnvlad
Дата сообщения: 12.07.2011 10:40
KF121

Цитата:
вот парочка полезный функций

функции может и полезные, но с выходом Excel 2007 несколько устарели
1) количество строк увеличено с 65536 до миллиона
2) количество столбцов увеличено c 256 (IV) до 16384 (XFD).
3) имя столбца может быть трех буквенным, и функция SwitchNumberToAlphabet для столбцов больше 27*26 (ZZ) вернет не то, что должна
Автор: KF121
Дата сообщения: 12.07.2011 10:42
я пока еще не сталкивался с такими объемами данных. и мне их хватало. а функции всегда можно подправить под те или иные нужды
Автор: KorolCOOL
Дата сообщения: 12.07.2011 11:57
Как узнать является ли содержимое строки S тем, что можно перевести в данные типа ДАТА?
Автор: smirnvlad
Дата сообщения: 12.07.2011 12:26
KorolCOOL

Цитата:
Как узнать является ли содержимое строки S тем, что можно перевести в данные типа ДАТА?


Код:
Function IsDateStr(S)
IsDateStr = False
On Error GoTo notadate
d = DateTime.DateValue(S)
IsDateStr = True
If Year(d) = Year(CDate(0)) Then IsDateStr = False
notadate:
End Function
Автор: SAS888
Дата сообщения: 12.07.2011 12:28
KorolCOOL

Цитата:
Как узнать является ли содержимое строки S тем, что можно перевести в данные типа ДАТА?
А что Вы подразумеваете под содержимым строки? Вообще-то, в Excel строка - это диапазон ячеек всех столбцов в строке листа. Если же S - это строковая переменная, то достаточно проверки
Код: If IsDate(S) Then...
Автор: KorolCOOL
Дата сообщения: 12.07.2011 13:15
Бинго. IsDate то, что нужно. Спасибо.

А не подскажете, если какая-нибудь функция, которая работала бы как IsDate но возвращала бы True если троковая переменная S содержит данные, которые можно не только перевести в Дату, но которые еще и подходят под какой-нибудь шаблон. А то IsDate возвращает True и на строку "2,1". А это уже перебор для моих целей.
Автор: SAS888
Дата сообщения: 13.07.2011 04:39
KorolCOOL

Цитата:
А то IsDate возвращает True и на строку "2,1". А это уже перебор для моих целей.


Вариант 1:
Возможно, что Вам достаточно следующего:

Код: If Not IsNumeric(s) Then If IsDate(s) Then MsgBox CDate(s)
Автор: TXP
Дата сообщения: 14.07.2011 11:14
Добрый день

Помогите пожалуйста оптимизировать

Sheets("По сумме").Range("Z41").Copy
Sheets("По сумме").Range("Z47").PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Автор: asbo
Дата сообщения: 14.07.2011 11:22
TXP
With Sheets("По сумме")
.Range("Z47").Value = .Range("Z41").Value
End With


Автор: TXP
Дата сообщения: 14.07.2011 12:10
Спасибо

Сие до ума доведите пожалуйста, а то не работает.

Данный код должен удалять в листе "Приложение № 1" данные в указанных ячейках"F13:BA50", кнопка находится на листе "Расчет"

Private Sub CBut4_Click()

Sheets("Приложение № 1").Select
Range("F13:BA50").Select
Selection.ClearContents
Range("F13:M14").Select
Sheets("Расчет").Select
Range("H11").Select
End Sub

В данном случае все наоборот с листа "Расчет" данные должны переноситься на лист "Приложение № 1"

Private Sub CBut2_Click()
Range("O13:BJ50").Select
Selection.Copy
Sheets("Приложение № 1").Select
Range("F13:BA50").Select
Selection.PasteSpecial Paste:=xlPasteValuesAndNumberFormats, Operation:= _
xlNone, SkipBlanks:=False, Transpose:=False
Range("F13:M14").Select
Sheets("Расчет").Select
Range("H12").Select
Application.CutCopyMode = False
End Sub

Автор: smirnvlad
Дата сообщения: 14.07.2011 12:14
Sheets("Приложение № 1").Range("F13:BA50").ClearContents
Автор: TXP
Дата сообщения: 14.07.2011 12:36
Спасибо заработало, по второму коду посоветуйте что нибудь
Автор: smirnvlad
Дата сообщения: 14.07.2011 13:13
TXP
можно так
Sheets("Расчет").Range("O13:BJ50").Copy Destination:= _
Sheets("Приложение № 1").Range("F13:BA50")
или через буфер и PasteSpecial
Sheets("Расчет").Range("O13:BJ50").Copy
Sheets("Приложение № 1").Range("F13:BA50").PasteSpecial _
Paste:=xlPasteValuesAndNumberFormats, Operation:= _
xlNone, SkipBlanks:=False, Transpose:=False
Application.CutCopyMode = False
Автор: TXP
Дата сообщения: 14.07.2011 14:27
Спасибо второй вариант подходит больше, т.к. так как первый копирует формулы а мне был необходим перенос контрольных данных.
Автор: asbo
Дата сообщения: 14.07.2011 14:57
TXP, smirnvlad
Dim vArr() As Variant
vArr = Range("O13:BJ50").Value
Range("F13:BA50").Value = vArr
Автор: smirnvlad
Дата сообщения: 14.07.2011 15:47
asbo
у меня таким способом формат ячейки странно себя ведет
например исходная ячейка - денежный, куда копируем - текстовый
формат меняется, но отображается сумма со знаком доллара вместо рублей, приходится вставлять дважды, т.е.
Dim vArr() As Variant
vArr = Range("O13:BJ50").Value
Range("F13:BA50").Value = vArr
Range("F13:BA50").Value = vArr
Автор: asbo
Дата сообщения: 14.07.2011 16:36
smirnvlad, не знаю... Но предполагаю, что:
- ячейки назначения уже имеют, какой-то формат, или
- Ексел автоматом назначает им некий формат в зависимости от типа копируемых данных, или
- Возникают какие-то нюансы VBA, при которых он изъясняется только по-американски.

И все это может быть и в комбинации. Пока не могу предметно ответить - надо поэкспериментровать.

Попробуй всунуть до и после каждого действия:
Debug.Print Range("F13:BA50").NumberFormat
Автор: smirnvlad
Дата сообщения: 14.07.2011 19:06
asbo

Цитата:
ячейки назначения уже имеют, какой-то формат

так и есть, т.е. excel сначала копирует данные, а потом форматирует их

почему тогда получаем $1.00, а не 1.00р., хотя формат тот же
после первого присвоения и после второго .NumberFormat и .NumberFormatLoacl совпадают, а .Value различаются
Автор: KorolCOOL
Дата сообщения: 15.07.2011 09:52
Просветите пожалуйста. Если я в программе использую переменные типа Object, то после выполнения программы, память, занимаемая этими переменными, автоматически освобождается или необходимо явно это сделать (насколько я знаю так: Set Var = Nothing)?
Автор: TXP
Дата сообщения: 15.07.2011 10:12
Добрый день

Подскажите как можно реализовать следующие:
1. При достижение определенного контрольного показателя в указанного в конкретной ячейке активизировался элемент управления (кнопка). грубо если значение ячейки А1 = 0 то кнопка "Печать" активна, если значение А1 отлично от 0 то кнопка не активна.
2. При нажатии кнопки "Печать" на листе "Расчет" распечатывались определенные листы (пример лист2, лист3 и т.д.) и при этом можно было задать определенное кол-во печати на тот или иной лист (например лист2 2 экз., лист3 1 экз.)

P.s. Повозможности если не затруднит напишете готовое решение т.к. в программировании не селен.
Автор: ZlydenGL
Дата сообщения: 15.07.2011 10:35
В модуле ЛИСТА задать процедуру

Код: Private Sub Worksheet_Change(ByVal Target As Range)
Автор: asbo
Дата сообщения: 15.07.2011 10:56
KorolCOOL

Цитата:
Если я в программе использую переменные типа Object, то после выполнения программы, память, занимаемая этими переменными, автоматически освобождается или необходимо явно это сделать (насколько я знаю так: Set Var = Nothing)?

Если вопрос именно по механизму выделения и освобождения памяти VBA, то лучше специализированный поиск по нему и делать. И по времени жизни и области видимости переменных в VBA.

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

Если же область видимости шире, чем процедура - то надо явно уничтожать. Говорят, что иногда и перед переназначением, но я не сталкивался. И, что касается Nothing, то, он не всегда корректно действует. Часто приходится использовать метод объекта .Close. В ответственных местах, чтобы не забивать голову я использую оба. Столкнулся с этим с некоторыми объектами Recordset.


Добавлено:
ZlydenGL
Наверное лучше: If Target = Range("$A$1")
Ни хрена не лучше :)

Добавлено:
smirnvlad
У меня все нормально работает, без трансформаций форматов. Вот пример. В ячейках A5-A7 данные. B1-B7 ссылаются на A5-A7. Копирование идет в D5-D7.

Код:
Sub sb_Copy()
Dim rSrc As Range, rTgt As Range
Dim vArr() As Variant

Set rSrc = Range("B5:B7")
Set rTgt = rSrc.Offset(0, 2)

'Debug.Print "- - - -" & vbLf: Call sb_Debug(rSrc): Call sb_Debug(rTgt)
vArr = rSrc.Value
Debug.Print "- - - -" & vbLf: Call sb_Debug(rSrc): Call sb_Debug(rTgt)
rTgt.Value = vArr
Debug.Print "- - - -" & vbLf: Call sb_Debug(rSrc): Call sb_Debug(rTgt)

End Sub

Sub sb_Debug(pRng As Range)
Dim cl As Range
For Each cl In pRng.Cells
With cl
Debug.Print .Address & "; " & _
.Formula & "; " & _
.Value & "; " & _
.NumberFormat & "; " & _
.NumberFormatLocal
End With
Next
Debug.Print vbLf
End Sub
Автор: coopercooper
Дата сообщения: 16.07.2011 16:30

Автор: TXP
Дата сообщения: 18.07.2011 12:36
Напишите код пожалуста.
Если значение формулы в ячейке А1 равно = 0, то CBut1.Enabled = True
Если значение формулы в ячейке А1 не равно = 0, то CBut1.Enabled = False

Страницы: 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127

Предыдущая тема: VS 2010


Форум Ru-Board.club — поднят 15-09-2016 числа. Цель - сохранить наследие старого Ru-Board, истории становления российского интернета. Сделано для людей.