Excel VBA函数确定行号

时间:2019-01-28 01:03:55

标签: excel vba function range

我构建了一个函数来确定数据所在的第一行。当我调用数据时,我不断收到错误消息,指出需要对象。如何解决该错误,这是实现目标的最佳方法吗? TYIA!

Sub rename()

Dim strOldType As String
Dim correctrow As Long
Dim a As Range

Set a = startrow(correctrow)

Range("s" & a).Select
strOldType = Selection.Value
End Sub

Function startrow(firstroww)
Dim strRow As String
Dim firstrow As Range

Range("ab1").Select
strRow = Selection.Value

If strRow <> "" Then
firstroww = 1
Else
Range("ab1").Activate
Selection.End(xlDown).Select
firstroww = ActiveCell.Row()
End If
End Function

4 个答案:

答案 0 :(得分:0)

您可以尝试这样的功能。您需要将范围传递到函数中,如以下Option Explicit Function FR(Start As Range) As Long Select Case Start Case <> "" FR = Start.Row Case Else FR = Start.End(xlDown).Row End Select End Function 所示。

自定义函数可以从任何起点在下面找到第一个使用的单元格。

Sub Test()

MsgBox FR(Range("A1"))

End Sub

original list [(4, 1), (3, 2), (1, 0), (2, 1)]
[(3, 2), (1, 0), (2, 1), 0.0]
[3, 2, 1, 0, 2, 1, 0.0]

enter image description here

答案 1 :(得分:0)

  • 请勿尝试在函数内部使用“选择”。
  • 使用Set分配范围对象。 请勿使用Set为变量分配数字。
  • 下定决心要行号还是范围对象。您会在两者之间来回跳动,而不考虑结果。

更正的代码:

Sub rename()

    Dim strOldType As String
    Dim correctrow As Long
    Dim a As LONG     '<~~ correction

    correctrow = 1     '<~~ correction
    a = startrow(correctrow)     '<~~ correction

    strOldType = Range("s" & a).Value

End Sub

Function startrow(firstroww)

    if Range("ab" & firstrow) <> "" then     '<~~ correction
        startrow = firstrow
    else
        startrow = Range("ab" & firstrow).end(xldown).row
    end if

End Function

答案 2 :(得分:0)

列功能中的第一个单元格

假定您正在寻找要在Excel中使用的VBA函数以计算列的第一非空行(由范围指定)。

功能

  • Volatile方法将用户定义的函数标记为volatile。一种 每当发生以下情况时,都必须重新计算volatile函数 工作表上的任何单元格。重新计算了非易失性函数 仅当输入变量更改时(VBA帮助)。
  • 至少为了正确起见,您必须使用IsEmpty 而不是“”的原因,例如如果结果行中的单元格 包含一个计算结果为“”的公式,它将被忽略。
  • “查找方法版本”使用“查找”方法来计算第一行,该行比 最终版本,例如如果您将值输入到 列,即结果为1,然后隐藏第一行,结果为 最终版本将不是1。
  • 该公式可以与SelectRange插入同一列 柱。在某些情况下,结束版本无法显示正确的 结果或创建循环引用。因此,使用ThisCell End 版本中,如果在SelectRange列中未找到任何值,则返回0。

查找方法版本

Function FirstRowFind(SelectRange As Range) As Long

    Application.Volatile

    Dim FirstCell As Range

    With Columns(SelectRange.Column)
        Set FirstCell = .Find("*", .Cells(.Cells.Count), -4123, 1, 2, 1)
    End With

    If Not FirstCell Is Nothing Then
        FirstRowFind = FirstCell.Row
    End If

End Function

查找方法

代替

Set FirstCell = .Find("*", .Cells(.Cells.Count), -4123, 1, 2, 1)

您可以使用

Set FirstCell = .Find("*", .Cells(.Cells.Count), _
        xlFormulas, xlWhole, xlByColumns, xlNext)

Set FirstCell = .Find(What:="*", After:=.Cells(.Cells.Count), _
        LookIn:=xlFormulas, LookAt:=xlWhole, _
        SearchOrder:=xlByColumns, SearchDirection:=xlNext)

可以省略参数LookAt(在这种情况下不重要)和SearchDirection(默认为Next)的参数,但是由于我找不到效率的差异,我没有。

在Excel中的用法

对于列AB

=FirstRowFind(AB1)
=FirstRowFind(AB20)
=FirstRowFind(AB17:AH234)

最终版本(不推荐)

Function FirstRowEnd(SelectRange As Range) As Long

    Application.Volatile

    Dim FirstCell As Range

    If Application.ThisCell.Column = SelectRange.Column Then Exit Function

    If Not IsEmpty(SelectRange.Cells(1)) Then
        FirstRowEnd = 1
      Else
        Set FirstCell = Cells(1, SelectRange.Column).End(xlDown)
        FirstRowEnd = FirstCell.Row
        If FirstRowEnd = Rows.Count And IsEmpty(FirstCell) Then
            FirstRowEnd = 0
        End If
    End If

End Function

在Excel中的用法

对于列AB

=FirstRowEnd(AB1)
=FirstRowEnd(AB20)
=FirstRowEnd(AB17:AH234)

答案 3 :(得分:0)

您可以使用此:

import UIKit

class ThirdViewController: UIViewController,UICollectionViewDelegate,UICollectionViewDataSource,UICollectionViewDelegateFlowLayout {


    @IBOutlet var collection_chess: UICollectionView!
    @IBOutlet var collection_bottom: UICollectionView!

    var originalIndexPath:IndexPath? = nil
    var draggingIndexPath:IndexPath? = nil
    var draggingView: UIView?
    var dragOffset: CGPoint = CGPoint(x: 0 , y: 0)

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
    }



    //-----------------------------------------------------------------------------------
    // MARK: - collection DataSource & Delegate
    //-----------------------------------------------------------------------------------



    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {

        if(collectionView == self.collection_chess)
        {
            return 64
        }else
        {
            return 10
        }



    }

    // make a cell for each cell index path
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {

        if(collectionView == self.collection_chess)
        {
            let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "chessCell", for: indexPath as IndexPath) as! chessCell

            cell.lbl_name.text = String(indexPath.row+1)


            if indexPath.row % 2 == 0{
                cell.backgroundColor = UIColor.white
            }else {
                cell.backgroundColor = UIColor.red
            }

            return cell

        }else
        {
            let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "chessimgCell", for: indexPath as IndexPath) as! chessimgCell

            cell.lbl_name.text = String(indexPath.row+1)



            cell.backgroundColor = UIColor.red


            return cell
        }

    }
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {


        return CGSize(width: collectionView.frame.size.width/8, height: collectionView.frame.size.width/8 )



    }
    public func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath)
    {

    }
    //    public func collectionView(_ collectionView: UICollectionView, moveItemAt sourceIndexPath: IndexPath, to destinationIndexPath: IndexPath) {
    //
    //    }
    //    public func collectionView(_ collectionView: UICollectionView, canMoveItemAt indexPath: IndexPath) -> Bool {
    //        return false
    //    }

    @IBAction func longPressGestureChanged(recognizer: UILongPressGestureRecognizer) {

        let globalLocation = recognizer.location(in: view)

        if self.collection_chess.frame.contains(globalLocation) {

            print("yes")

            let location = recognizer.location(in: collection_chess!)
            switch recognizer.state {
            case .began: startDragAtLocation(location: location)
            case .changed: updateDragAtLocation(location: location)
            case .ended: endDragAtLocation(location: location)
            default:
                break
            }

        } else if collection_bottom.frame.contains(globalLocation) {

            print("NO")

        } else {
            //you do not cover any of collection views
        }
    }

    //...Handling the Start of a Drag

    func startDragAtLocation(location: CGPoint) {
        guard let cv = self.collection_chess else {

            return

        }
        guard let indexPath = cv.indexPathForItem(at: location) else {
            //print("This is return1 ----->")
            return }
        //        guard cv.dataSource?.collectionView?(cv, canMoveItemAt: indexPath) == true else {
        //            //print("This is return2 ----->")
        //            return
        //
        //        }
        guard let cell = cv.cellForItem(at: indexPath) else {


            return }

        originalIndexPath = indexPath
        draggingIndexPath = indexPath
        draggingView = cell.snapshotView(afterScreenUpdates: true)
        draggingView!.frame = cell.frame
        //cv.addSubview(draggingView!)
        self.view.addSubview(draggingView!)

        dragOffset = CGPoint(x: draggingView!.center.x - location.x, y:draggingView!.center.y - location.y)
        //dragOffset = CGPoint(x: draggingView!.center.x - self.view.frame.origin.x, y:draggingView!.center.y - self.view.frame.origin.y)
        draggingView?.layer.shadowPath = UIBezierPath(rect: draggingView!.bounds).cgPath
        draggingView?.layer.shadowColor = UIColor.black.cgColor
        draggingView?.layer.shadowOpacity = 0.8
        draggingView?.layer.shadowRadius = 10

        // invalidateLayout()

        UIView.animate(withDuration: 0.4, delay: 0, usingSpringWithDamping: 0.4, initialSpringVelocity: 0, options: [], animations: {
            self.draggingView?.alpha = 0.95
            self.draggingView?.transform = CGAffineTransform(scaleX: 1.2, y: 1.2)
        }, completion: nil)
    }


    func updateDragAtLocation(location: CGPoint) {
        guard let view = draggingView else {
            print("This is return2 ----->")
            return }
        guard let cv = collection_chess else {
            print("This is return3 ----->")
            return }

        view.center = CGPoint(x: location.x + dragOffset.x  , y: location.y + dragOffset.y )



        //        if let newIndexPath = cv.indexPathForItem(at: location) {
        //            cv.moveItem(at: draggingIndexPath!, to: newIndexPath)
        //            draggingIndexPath = newIndexPath
        //        }
    }


    func endDragAtLocation(location: CGPoint) {

        print("This is end ----",originalIndexPath?.row)
        print(" ----",draggingIndexPath?.row)



        guard let dragView = draggingView else { return }
        guard let indexPath = draggingIndexPath else { return }
        guard let cv = collection_bottom else { return }
        guard let datasource = cv.dataSource else { return }

        let targetCenter = datasource.collectionView(cv, cellForItemAt: indexPath).center

        let shadowFade = CABasicAnimation(keyPath: "shadowOpacity")
        shadowFade.fromValue = 0.8
        shadowFade.toValue = 0
        shadowFade.duration = 0.4
        dragView.layer.add(shadowFade, forKey: "shadowFade")

        UIView.animate(withDuration: 0.4, delay: 0, usingSpringWithDamping: 0.4, initialSpringVelocity: 0, options: [], animations: {
            dragView.center = targetCenter
            //dragView.transform = CGAffineTransformIdentity

        }) { (completed) in

            if indexPath != self.originalIndexPath! {
                // datasource.collectionView ?? <#default value#>(cv, moveItemAt: self.originalIndexPath!, to: indexPath)
                //datasource.collectionView?(cv, moveItemAtIndexPath: self.originalIndexPath!, toIndexPath: indexPath)
            }

            dragView.removeFromSuperview()
            self.draggingIndexPath = nil
            self.draggingView = nil
            //self.invalidateLayout()
        }
    }


}

UsedRange对象是覆盖所有非空单元格的最大矩形。