You can use the following basic syntax to calculate the minimum value in a range using VBA:
Sub MinValue()
Range("D2") = WorksheetFunction.Min(Range("B2:B11"))
End Sub
This particular example calculates the minimum value in the range B2:B11 and assigns the result to cell D2.
If you would instead like to display the minimum value in a message box, you can use the following syntax:
Sub MinValue()
'Create variable to store min value
Dim minValue As Single
'Calculate min value in range
minValue = WorksheetFunction.Min(Range("B2:B11"))
'Display the result
MsgBox "Min Value in Range: " & minValue
End Sub
The following examples shows how to use each of these methods in practice with the following dataset in Excel that contains information about various basketball players:
Related: How to Find Max Value in Range Using VBA
Example 1: Calculate Minimum Value of Range Using VBA and Display Results in Cell
Suppose we would like to calculate the minimum value in the points column and output the results in a specific cell.
We can create the following macro to do so:
Sub MinValue()
Range("D2") = WorksheetFunction.Min(Range("B2:B11"))
End Sub
When we run this macro, we receive the following output:
Notice that cell D2 contains a value of 10.
This tells us that the minimum value in the points column is 10.
Example 2: Calculate Minimum Value of Range Using VBA and Display Results in Message Box
Suppose we would instead like to calculate the minimum value in the points column and output the results in a message box.
We can create the following macro to do so:
Sub MinValue()
'Create variable to store min value
Dim minValue As Single
'Calculate min value in range
minValue = WorksheetFunction.Min(Range("B2:B11"))
'Display the result
MsgBox "Min Value in Range: " & minValue
End Sub
When we run this macro, we receive the following output:
The message box tells us that the minimum value in the range B2:B11 is 10.
Note that in this example we calculated the minimum value in the range B2:B11.
However, if you’d like to instead calculate the minimum value in an entire column you could type B:B instead.
This will calculate the minimum value in all of column B.
Additional Resources
The following tutorials explain how to perform other common tasks in VBA:
VBA: How to Calculate Average Value of Range
VBA: How to Count Number of Rows in Range
VBA: How to Sum Values in Range
For a list like:
Column1 Column2 Column3
DataA 1 1234
DataA 2 4678
DataA 3 8910
DataB 2 1112
DataB 4 1314
DataB 9 1516
How do I get a list like this:
Column4 Column5 Column6
DataA 1 1234
DataB 2 1112
The key is to only return the minimum value in column2 and its corresponding column3 value.
Ben McCormack
31.9k46 gold badges146 silver badges222 bronze badges
asked Dec 9, 2009 at 20:08
4
Sorry I misunderstood your Question First. Here is a working code that ended up more complex than I wanted it to be
Option Explicit
Private Function inCollection(ByRef myCollection As Collection, ByRef value As Variant) As Boolean
Dim i As Integer
inCollection = False
For i = 1 To myCollection.Count
If (myCollection(i) = value) Then
inCollection = True
Exit Function
End If
Next i
End Function
Sub listMinimums()
Dim source As Range
Dim target As Range
Dim row As Range
Dim i As Integer
Dim datas As New Collection
Dim minRows As New Collection
Set source = Range("A2:C5")
Set target = Range("D2")
target.value = source.value
For Each row In source.Rows
With row.Cells(1, 1)
If (inCollection(datas, .value) = False) Then
datas.Add .value
minRows.Add row.row, .value
End If
If (Me.Cells(minRows(.value), 2) > row.Cells(1, 2)) Then
minRows.Remove (.value)
minRows.Add row.row, .value
End If
End With
Next row
'output'
For i = 1 To minRows.Count
target(i, 1) = Me.Cells(minRows(i), 1)
target(i, 2) = Me.Cells(minRows(i), 2)
target(i, 3) = Me.Cells(minRows(i), 3)
Next i
Set datas = Nothing
Set minRows = Nothing
End Sub
Note: You might want to replace Me
with the name of your sheet.
answered Dec 9, 2009 at 21:01
margmarg
2,7871 gold badge30 silver badges33 bronze badges
An example using ADO.
Dim cn As Object
Dim rs As Object
Dim strFile As String
Dim strCon As String
Dim strSQL As String
Dim i As Integer
''http://support.microsoft.com/kb/246335
strFile = ActiveWorkbook.FullName
strCon = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & strFile _
& ";Extended Properties=""Excel 8.0;HDR=Yes;IMEX=1"";"
Set cn = CreateObject("ADODB.Connection")
Set rs = CreateObject("ADODB.Recordset")
cn.Open strCon
strSQL = "SELECT Column1, Min(Column3) As MinCol3 FROM [Sheet8$] GROUP BY Column1"
rs.Open strSQL, cn, 3, 3
For i = 0 To rs.fields.Count - 1
Sheets("Sheet7").Cells(1, i + 1) = rs.fields(i).Name
Next
Worksheets("Sheet7").Cells(2, 1).CopyFromRecordset rs
answered Dec 10, 2009 at 19:39
FionnualaFionnuala
90.2k7 gold badges112 silver badges151 bronze badges
2
Try this:
Public Sub MinList()
Const clColKey_c As Long = 1&
Const clColVal_c As Long = 3&
Dim ws As Excel.Worksheet, objDict As Object
Dim lRow As Long, dVal As Double, sKey As String
Dim lRowFrst As Long, lRowLast As Long, lColOut As Long
Set ws = Excel.ActiveSheet
Set objDict = CreateObject("Scripting.Dictionary")
lRowFrst = ws.UsedRange.Row
lRowLast = ws.UsedRange.Rows.Count
lColOut = ws.UsedRange.Columns.Count + 1&
For lRow = lRowFrst To lRowLast
dVal = Val(ws.Cells(lRow, clColVal_c).Value)
sKey = ws.Cells(lRow, clColKey_c).Value
If objDict.Exists(sKey) Then
If dVal > objDict.Item(sKey) Then objDict.Item(sKey) = dVal
Else
objDict.Add sKey, dVal
End If
Next
For lRow = lRowFrst To lRowLast
ws.Cells(lRow, lColOut).Value = objDict.Item(ws.Cells(lRow, clColKey_c).Value)
Next
ws.Cells(1&, lColOut).Value = "Min"
End Sub
answered Dec 11, 2009 at 13:35
OorangOorang
6,6201 gold badge35 silver badges52 bronze badges
all_angarsk, Вы меня не поняли. Я имел ввиду, что не нужно усложнять. Любой модуль/процедуру Вы легко отправите в экспорт на флэшку в формате *.bas. И так точно вытянете его оттуда в любом месте, на любом компе, в любой документ. А с модулем кнопки — тяжелее. Ну и с самой кнопкой — нарисуйте встроенными инстр-ми фигуру (или обьект WordArt) что Вам нравится, и назначьте ей нужную процедуру (правая кнопка > Назначить макрос (или как там у Вас по локализации)). Всего пару кликов. И практично, и веселее, и проще, а не унылая серость.
А про «…регулярные выражения…«. Что Вы имели ввиду? Я их там не вижу.
Добавлено через 25 минут
Кажется, я понял про регулярку. Смотрите, у Тoiai грамотный и лаконичный код. Лично я бы все-таки сгенерированный массив выгрузил на лист, чтоб было видно. I.e., после next я бы добавил строку:
[a1].resize(1, ubound(a)).value=a
Дальше он вызывает окно сообщения MsgBox, в котором использует фукции не VBA, а Excel — Min и Max. Поэтому его тяжелая жизнь заставила вызывать их такими фразами Application.Max(a), Application.Min(a)…
Кстати, что б, если не нужно, не выкладывать массив на лист, его тоже можно одним движение загнать в этот же MsgBox.
tvit Пользователь Сообщений: 60 |
Дано: Подскажите пожалуйста как это сделать? Прикрепленные файлы
|
gling Пользователь Сообщений: 4030 |
А почему не преобразовать в числа? Прикрепленные файлы
|
JeyCi Пользователь Сообщений: 3387 |
а Поиск не помогает? здесь … переменные брать типа As Date по логике тех строк — и будет вам вариант получше формулы на вба, полагаю… (изначально весь ваш Range возьмите в массив — arr)… успехов Изменено: JeyCi — 17.03.2015 21:41:32 чтобы не гадать на кофейной гуще, кто вам отвечает и после этого не совершать кучу ошибок — обратитесь к собеседнику на ВЫ — ответ на ваш вопрос получите — а остальное вас не касается (п.п.п. на форумах) |
МВТ Пользователь Сообщений: 1198 |
#4 17.03.2015 21:41:26 Выводит максимальную дату в выделенном диапазоне
|
||
Мотя Пользователь Сообщений: 3218 |
Уважаемый tvit ! Изменено: Мотя — 17.03.2015 21:54:23 |
tvit Пользователь Сообщений: 60 |
Спасибо за ответы. но к сожалению все не то. to Gling: то что предлагаете Вы у меня уже есть в моем вопросе. но тут используется дополнительная ячейка. а мне нужно сразу присвоить переменной. |
Может так? (честно не совсем понял как надо) |
|
tvit Пользователь Сообщений: 60 |
Вы сначала вычисления присваиваете ячейке, а затем значение ячейки присваиваете переменной. А я спрашиваю как сразу присвоить переменной, не используя вспомогательных ячеек |
JeyCi Пользователь Сообщений: 3387 |
#9 18.03.2015 10:23:36
tvit я вам посоветовала воспользоваться Поиском (линки сбились — но эта вкладка находится вверху страницы около Пользователи и Правила) — MIN в Поиск — и уже с первого листа Поисковика видны примеры… вариант для любого числа (включая дробное)
в вашей ситуации, как видите, проблема НЕ в способе поиска мин и макс, а в нач форматах ваших данных… ищите способ объяснить xl что он смотрит на даты — я с ходу точно не знаю как… успехов Изменено: JeyCi — 09.05.2015 14:40:38 чтобы не гадать на кофейной гуще, кто вам отвечает и после этого не совершать кучу ошибок — обратитесь к собеседнику на ВЫ — ответ на ваш вопрос получите — а остальное вас не касается (п.п.п. на форумах) |
||||
Максим Зеленский Пользователь Сообщений: 4655 Microsoft MVP 2018-2022 |
#10 18.03.2015 12:11:55 tvit, думаю, что без цикла никак. Попытки запихнуть вашу функцию в Evaluate не увенчались успехом (что странно, так как массивные функции обрабатываются ею нормально), возможно, причина в том, что EVALUATE не хочет работать с вложенной VALUE или DATEVALUE из-за того, что даты не в буржуйском формате.
а это нет
а вот это — работает, если в С1:С4 поместить например 1,2,3,4 в текстовом формате:
F1 творит чудеса |
||||||
МВТ Пользователь Сообщений: 1198 |
#11 18.03.2015 12:25:02 tvit,вообще-то, работает, просто не присваивает значения переменной, а выводит в текстовом формате. А для того, чтобы код знал, что вам нужна дата, то и объявите переменную, как дату:
У меня, во всяком случае, этот макрос работает |
||
JeyCi Пользователь Сообщений: 3387 |
#12 18.03.2015 12:53:32
думаю так же… ещё один вариант (от поисковика
Изменено: JeyCi — 09.05.2015 14:40:53 чтобы не гадать на кофейной гуще, кто вам отвечает и после этого не совершать кучу ошибок — обратитесь к собеседнику на ВЫ — ответ на ваш вопрос получите — а остальное вас не касается (п.п.п. на форумах) |
||||
JeyCi Пользователь Сообщений: 3387 |
#13 18.03.2015 13:10:01
у меня выдает 01.01.1900 — xl 2010 ru — Изменено: JeyCi — 09.05.2015 14:41:04 чтобы не гадать на кофейной гуще, кто вам отвечает и после этого не совершать кучу ошибок — обратитесь к собеседнику на ВЫ — ответ на ваш вопрос получите — а остальное вас не касается (п.п.п. на форумах) |
||
МВТ Пользователь Сообщений: 1198 |
JeyCi, а Вы диапазон с датами выделили? Макрос работает с Selection |
tvit Пользователь Сообщений: 60 |
Спасибо всем откликнувшимся. Если без цикла никак, тогда проще найти свободную ячейку в Excel и воспользоваться формулой массива |
JeyCi Пользователь Сообщений: 3387 |
#16 18.03.2015 13:28:54
в том то и дело, что как только не выделяла — работает только на две ячейки, в которых вставлена формула (b6:b7) — на (b1:b4) не работает… выдаёт то 00:00:00, то 01.01.1900… пробовала поколдовать с форматом ячеек — тоже какие-то странные итоги… вобщем, слабо поняла, как меня понимает xl… ну и ладно, Изменено: JeyCi — 09.05.2015 14:41:16 чтобы не гадать на кофейной гуще, кто вам отвечает и после этого не совершать кучу ошибок — обратитесь к собеседнику на ВЫ — ответ на ваш вопрос получите — а остальное вас не касается (п.п.п. на форумах) |
||
МВТ Пользователь Сообщений: 1198 |
Прикрепляю файл с вставленными макросом и пояснениями |
МВТ, так в том и дело, что изначально даты сохранены как текст. |
|
МВТ Пользователь Сообщений: 1198 |
#19 18.03.2015 14:28:55 Максим Зеленский,понял: протупил — я сам даты вводил. Так может, проще поменять формат дат на Дату
Изменено: МВТ — 18.03.2015 15:00:00 |
||
JeyCi Пользователь Сообщений: 3387 |
#20 18.03.2015 17:25:45
как вариант (с Selection) без цикла
ВСЁ — думаю, короче и без цикла у меня уже точно не получится… Изменено: JeyCi — 09.05.2015 14:41:29 чтобы не гадать на кофейной гуще, кто вам отвечает и после этого не совершать кучу ошибок — обратитесь к собеседнику на ВЫ — ответ на ваш вопрос получите — а остальное вас не касается (п.п.п. на форумах) |
||||
tvit Пользователь Сообщений: 60 |
#21 18.03.2015 18:42:51
Немного не то, что я просил (все таки идет изменение исходного файла), но решение очень красивое, нужно запомнить. Мне часто нужно делать нечто подобное, но все как-то извращенными способами приходилось это делать Изменено: tvit — 09.05.2015 14:41:47 |
||
tvit Пользователь Сообщений: 60 |
Максим Зеленский, пытался осмыслить, что Вы написали. Действительно, если в исходном файле заменить в датах точку на слеш «/» , то все начинает работать. Похоже глюк VBA, в оболочке русификация отрабатывает отлично, а в VBA нет. |
МВТ Пользователь Сообщений: 1198 |
tvit,если для вас настолько критично сохранять даты в текстовом формате, можете прописать в макросе создание в свободной колонке временного массива в правильном формате, его обработку и последующее удаление |
tvit Пользователь Сообщений: 60 |
Обрабатываемые данные выгружаются в текстовые файлы из централизованной АС и на них я повлиять ни как не могу. А поскольку объем каждого из этих файлов может занимать 300-400 Мб по 500 тысяч строк и более, то вопрос с нехваткой памяти стоит достаточно остро, поэтому прежде чем добавить вспомогательный столбец, я 10 раз подумаю. |
Казанский Пользователь Сообщений: 8839 |
#25 19.03.2015 00:38:58
Но Вы можете влиять на импорт текстов в Excel. Используйте Мастер импорта текстов (он запускается автоматически при открытии файлов .txt) и задайте формат Дата:ДМГ нужному столбцу. |
||
Максим Зеленский Пользователь Сообщений: 4655 Microsoft MVP 2018-2022 |
#26 19.03.2015 09:30:03
связано скорее с тем, что функции преобразования типов в VBA не работают с массивами напрямую (только с элементами), а прямого аналога функции ЗНАЧЕН в объекте WorksheetFunction нет. Фактически, в рамках поставленных вами условий (без циклов, без задействования дополнительных столбцов) получить результат можно было только при использовании метода Evaluate, запихивая в него готовую формулу. EVALUATE — наследие XML, предшественника VBA, и кроме даты в US-формате, есть еще некоторые ограничения. Для прочих сложностей с международными стандартами в VBA есть Application.International с кучей региональных настроек. Изменено: Максим Зеленский — 09.05.2015 14:42:48 F1 творит чудеса |
||
The Excel MIN function returns the smallest value from a specified range of numeric values
Example: Excel MIN Function
METHOD 1. Excel MIN Function
EXCEL
Result in cell C10 (-7) — returns the smallest numeric value from the selected range. |
Result in cell D10 (2) — returns the smallest numeric value from the selected range. |
METHOD 2. Excel MIN function using the Excel built-in function library
EXCEL
Formulas tab > Function Library group > More Functions > Statistical > MIN > populate the input box
=MIN(C5:C9) Note: in this example we are populating an input box with a single range. |
METHOD 1. Excel MIN function using VBA
VBA
Sub Excel_MIN_Function()
‘declare a variable
Dim ws As Worksheet
Set ws = Worksheets(«MIN»)
‘apply the Excel MIN function
ws.Range(«C10») = Application.WorksheetFunction.Min(ws.Range(«C5:C9»))
ws.Range(«D10») = Application.WorksheetFunction.Min(ws.Range(«D5:D9»))
End Sub
OBJECTS
Worksheets: The Worksheets object represents all of the worksheets in a workbook, excluding chart sheets.
Range: The Range object is a representation of a single cell or a range of cells in a worksheet.
PREREQUISITES
Worksheet Name: Have a worksheet named MIN.
ADJUSTABLE PARAMETERS
Output Range: Select the output range by changing the Range references («C10») and («D10») in the VBA code to any cell in the worksheet, that doesn’t conflict with the formula.
Usage of the Excel MIN function and formula syntax
EXPLANATION
DESCRIPTION
The Excel MIN function returns the smallest value from a specified range of numeric values.
SYNTAX
=MIN(number1, [number2], …)
ARGUMENT(S)
number1: (Required) A single numeric cell or a range of numeric cells.
number2: (Optional) A single numeric cell or a range of numeric cells.
ADDITIONAL NOTES
Note 1: In Excel 2007 and later the MIN function can accept up to 255 number arguments. In Excel 2003 the MIN function can only accept up to 30 number arguments.