Я попробовал раз писать об этом, но в конце концов я сдался, так как правила несколько размыты. В принципе, вам придется повесить его.
Возможно, лучше сосредоточиться на том, где фигурные скобки и скобки могут использоваться взаимозаменяемо: при передаче параметров вызовам метода. Вы можете заменить скобку фигурными скобками, если и только если метод ожидает единственный параметр. Например:
List(1, 2, 3).reduceLeft{_ + _} // valid, single Function2[Int,Int] parameter
List{1, 2, 3}.reduceLeft(_ + _) // invalid, A* vararg parameter
Тем не менее, вам нужно больше знать, чтобы лучше понять эти правила.
Авторы Spray рекомендуйте круглые парсеры, потому что они дают повышенную проверку компиляции. Это особенно важно для DSL, таких как Spray. Используя parens, вы сообщаете компилятору, что ему должна быть предоставлена только одна строка; поэтому, если вы случайно дадите ему два или более, он будет жаловаться. Теперь это не так с фигурными фигурными скобками - если, например, вы где-то забыли оператор, тогда ваш код будет компилироваться, и вы получите неожиданные результаты и потенциально очень сложную ошибку. Ниже изобретено (так как выражения чисты и, по крайней мере, дают предупреждение), но делает точку:
method {
1 +
2
3
}
method(
1 +
2
3
)
Первые компиляции, вторая дает error: ')' expected but integer literal found
. Автор хотел написать 1 + 2 + 3
.
Можно утверждать, что это похоже на многопараметрические методы с аргументами по умолчанию; невозможно случайно забыть запятую, чтобы отделять параметры при использовании парнеров.
Важное часто забытое примечание о многословии. Использование фигурных скобок неизбежно приводит к подробному коду, поскольку руководство стиля Scala четко заявляет, что закрытие фигурных скобок должно быть в их собственной строке:
... закрывающая фигурная скобка находится на ее собственной строки сразу после последней строки функции.
blockquote>Многие автореформаторы, как и в IntelliJ, автоматически выполнит эту переформатировку для вас. Так что старайтесь использовать круглые паренны, когда сможете.
Инфиксная нотация
При использовании инфиксной нотации, например
List(1,2,3) indexOf (2)
, вы можете опустить скобки, если есть только один параметр и записать его какList(1, 2, 3) indexOf 2
. Это не относится к точечной нотации.Обратите также внимание, что если у вас есть один параметр, который является выражением с несколькими токенами, например
x + 2
илиa => a % 2 == 0
, вы должны использовать скобки для указания границы выражения.Кортежи
Поскольку вы иногда можете опускать скобки, иногда кортеж нуждается в дополнительных скобках, например, в
((1, 2))
, а иногда внешняя скобка может быть опущена, например в(1, 2)
. Это может вызвать путаницу.Функциональные / частичные литералы функции с
case
Scala имеет синтаксис для литералов функций и частичных функций. Это выглядит так:
{ case pattern if guard => statements case pattern => statements }
Единственными другими местами, где вы можете использовать
case
заявления, являются ключевые словаmatch
иcatch
:object match { case pattern if guard => statements case pattern => statements }
try { block } catch { case pattern if guard => statements case pattern => statements } finally { block }
Вы не можете использовать выражения
case
в любом другом контексте . Итак, если вы хотите использоватьcase
, вам нужны фигурные скобки . В случае, если вам интересно, что делает различие между функцией и литералом частичной функции, ответ таков: контекст. Если Scala ожидает функцию, вы получите функцию. Если он ожидает частичную функцию, вы получаете частичную функцию. Если оба они ожидаются, это дает ошибку в двусмысленности.Выражения и блоки
Скобки могут использоваться для создания подвыражений. Кудрявые фигурные скобки можно использовать для создания блоков кода (это не литер функций, поэтому не стоит пытаться использовать его как один). Блок кода состоит из нескольких операторов, каждый из которых может быть оператором импорта, объявлением или выражением. Это происходит следующим образом:
{ import stuff._ statement ; // ; optional at the end of the line statement ; statement // not optional here var x = 0 // declaration while (x < 10) { x += 1 } // stuff (x % 5) + 1 // expression } ( expression )
Итак, если вам нужны декларации, несколько операторов,
import
или что-то в этом роде, вам нужны фигурные скобки. И поскольку выражение является выражением, скобки могут появляться внутри фигурных скобок. Но интересно то, что блоками кода являются выражения также , поэтому вы можете использовать их где угодно внутри выражение:( { var x = 0; while (x < 10) { x += 1}; x } % 5) + 1
Итак, поскольку выражения - это выражения, а блоки кодов - выражения, все ниже:
1 // literal (1) // expression {1} // block of code ({1}) // expression with a block of code {(1)} // block of code with an expression ({(1)}) // you get the drift...
Где они не взаимозаменяемы
В принципе, вы не можете заменить
{}
на()
или наоборот в другом месте. Например:while (x < 10) { x += 1 }
Это не вызов метода, поэтому вы не можете записать его каким-либо другим способом. Ну, вы можете поместить фигурные скобки внутри в скобки для
condition
, а также использовать скобки внутри фигурные скобки для блока кода:while ({x < 10}) { (x += 1) }
Итак, я надеюсь, что это поможет.
Вам нужно будет добавить цикл для циклического прохождения каждой строки. Вы сделали часть работы, найдя последний ряд. Вы также установили первую строку на Rngheaders
, но не использовали.
Dim ws As Worksheet
Dim lrow As Long
Dim AmountCol as Long
Dim BillCol as Long
Dim USDCol as Long
Dim Rngheaders As Range
Dim x as long
Set ws = ThisWorkbook.Sheets("CSV Data PR")
Set Rngheaders = ws.Range("1:1")
lrow = ws.Cells(Rows.Count, 1).End(xlUp).Row
AmountCol = Rngheaders.Find(What:="Amount").Column
BillCol = Rngheaders.Find(What:="Bill.qty").Column
USDCol = Rngheaders.Find(What:="In USD").Column
For x= 2 to lrow
ws.Cells(x,USDCol) = ws.Cells(x, AmountCol) * ws.Cells(x, BillCol)
Next x
Попробуйте этот код:
Dim ws As Worksheet
Dim lrow As Long
Dim Amount As Range
Dim Bill As Range
Dim USD As Range
Dim Rngheaders As Range
Dim counter As Integer
Set ws = ThisWorkbook.Sheets("CSV Data PR")
Set Rngheaders = ws.Range("1:1")
lrow = ws.Cells(Rows.count, 1).End(xlUp).Row - 1
Set Amount = ws.Rows(1).Find(What:="Amount")
Set Bill = ws.Rows(1).Find(What:="Bill.qty")
Set USD = ws.Rows(1).Find(What:="In USD")
For counter = 1 To lrow
USD.Offset(counter, 0).Value = Amount.Offset(counter, 0).Value * Bill.Offset(counter, 0).Value
Next counter
Я установил тип переменной диапазонов Суммы, Билла и USD
Поскольку это уже диапазоны, вы можете обращаться к ним напрямую. Не нужно использовать Range(USD.Address)
Кроме того, вы не используете эту строку: Set Rngheaders = ws.Range("1:1")
Попробуйте и дайте мне знать, если это работает. Я не мог проверить это.