Cách triển khai thuật toán dựa trên Set / UDF


13

Tôi có một thuật toán mà tôi cần để chạy với mọi hàng trong một bảng có 800K hàng và 38 cột. Thuật toán được triển khai trong VBA và thực hiện một loạt phép toán sử dụng các giá trị từ một số cột để thao tác với các cột khác.

Tôi hiện đang sử dụng Excel (ADO) để truy vấn SQL và sử dụng VBA với các con trỏ phía máy khách để áp dụng thuật toán theo vòng lặp qua mỗi hàng. Nó hoạt động nhưng mất 7 giờ để chạy.

Mã VBA đủ phức tạp để có thể mã hóa lại thành T-SQL.

Tôi đã đọc về tích hợp CLR và UDF như các tuyến có thể. Tôi cũng đã nghĩ đến việc đưa mã VBA vào một tác vụ kịch bản SSIS để đến gần hơn với cơ sở dữ liệu nhưng chắc chắn một phương pháp chuyên môn cho loại vấn đề hiệu năng này tồn tại.

Lý tưởng nhất là tôi có thể chạy thuật toán dựa trên càng nhiều hàng (tất cả?) Càng tốt theo cách đặt song song.

Bất kỳ trợ giúp nào được xác nhận rất nhiều về cách có được hiệu suất tốt nhất với loại vấn đề này.

--Biên tập

Cảm ơn các ý kiến, tôi đang sử dụng MS SQL 2014 Enterprise, đây là một số chi tiết:

Thuật toán tìm các mẫu đặc trưng trong dữ liệu chuỗi thời gian. Các hàm trong thuật toán thực hiện làm mịn đa thức, cửa sổ và tìm các vùng quan tâm dựa trên các tiêu chí đầu vào, trả về một tá giá trị và một số kết quả Boolean.

Câu hỏi của tôi là về phương pháp luận hơn là thuật toán thực tế: Nếu tôi muốn đạt được tính toán song song trên nhiều hàng cùng một lúc, các tùy chọn của tôi là gì.

Tôi thấy mã lại vào T-SQL được khuyến nghị rất nhiều công việc nhưng có thể, tuy nhiên nhà phát triển thuật toán hoạt động trong VBA và nó thay đổi thường xuyên nên tôi cần giữ đồng bộ với phiên bản T-SQL và xác thực lại mỗi thay đổi.

Có phải T-SQL là cách duy nhất để thực hiện các hàm dựa trên tập hợp?


3
SSIS có thể cung cấp một số song song hóa giả định rằng bạn thiết kế luồng dữ liệu của mình tốt. Đó là nhiệm vụ mà bạn đang tìm kiếm vì bạn cần thực hiện tính toán theo hàng này. Nhưng điều đó nói rằng, trừ khi bạn có thể cung cấp cho chúng tôi chi tiết cụ thể (lược đồ, các tính toán liên quan và những gì các tính toán này hy vọng đạt được), không thể giúp bạn tối ưu hóa. Họ nói rằng việc viết các thứ trong lắp ráp có thể tạo ra mã nhanh nhất nhưng nếu như tôi, bạn hút nó một cách khủng khiếp, thì nó sẽ không hiệu quả chút nào
billinkc

2
Nếu bạn xử lý từng hàng một cách độc lập, thì bạn có thể chia 800K hàng thành Ncác lô và chạy các Ntrường hợp thuật toán của bạn trên Ncác bộ xử lý / máy tính riêng biệt. Mặt khác, nút cổ chai chính của bạn là gì - chuyển dữ liệu từ SQL Server sang Excel hoặc tính toán thực tế? Nếu bạn thay đổi chức năng VBA để trả về một số kết quả giả ngay lập tức, toàn bộ quá trình sẽ mất bao lâu? Nếu vẫn mất hàng giờ, thì nút cổ chai đang truyền dữ liệu. Nếu phải mất vài giây, thì bạn cần tối ưu hóa mã VBA thực hiện tính toán.
Vladimir Baranov

Đó là bộ lọc được gọi là thủ tục được lưu trữ: SELECT AVG([AD_Sensor_Data]) OVER (ORDER BY [RowID] ROWS BETWEEN 5 PRECEDING AND 5 FOLLOWING) as 'AD_Sensor_Data' FROM [AD_Points] WHERE [FileID] = @FileID ORDER BY [RowID] ASC Trong Management Studio, chức năng này được gọi cho mỗi hàng mất 50mS
medwar19

1
Vì vậy, truy vấn mất 50 ms và thực hiện 800000 lần (11 giờ) là những gì đang mất thời gian. Là @FileID duy nhất cho mỗi hàng hoặc có trùng lặp để bạn có thể giảm thiểu số lần bạn cần để thực hiện truy vấn không? Bạn cũng có thể tính toán trước khi sử dụng avg cho tất cả các tệp cho bảng sắp xếp trong một lần (sử dụng phân vùng trên FileID) và sau đó truy vấn bảng đó mà không cần chức năng cửa sổ cho mỗi hàng. Thiết lập tốt nhất cho bảng phân tầng có vẻ như phải có một chỉ mục được nhóm (FileID, RowID).
Mikael Eriksson

1
Tốt nhất là nếu bạn bằng cách nào đó có thể loại bỏ sự cần thiết phải chạm vào db cho mỗi hàng. Điều đó có nghĩa là bạn phải truy cập TSQL và có thể tham gia truy vấn avg hoặc tìm đủ thông tin cho mỗi hàng để mọi thứ thuật toán cần có ngay trên hàng, có thể được mã hóa theo cách nào đó nếu có nhiều hàng con tham gia (xml) .
Mikael Eriksson

Câu trả lời:


8

Liên quan đến phương pháp luận, tôi tin rằng bạn đang sủa sai cây b;;).

Những gì chúng ta biết:

Trước tiên, hãy củng cố và xem xét những gì chúng ta biết về tình huống:

  • Một số tính toán phức tạp cần được thực hiện:
    • Điều này cần phải xảy ra trên mỗi hàng của bảng này.
    • Thuật toán thay đổi thường xuyên.
    • Thuật toán ... [sử dụng] các giá trị từ một số cột để thao tác với các cột khác
    • Thời gian xử lý hiện tại là: 7 giờ
  • Cái bàn:
    • chứa 800.000 hàng.
    • có 38 cột.
  • Ứng dụng back-end:
  • Cơ sở dữ liệu là SQL Server 2014, Enterprise Edition.
  • Có một Thủ tục lưu trữ được gọi cho mỗi hàng:

    • Điều này mất 50 ms (trên avg, tôi giả sử) để chạy.
    • Nó trả về khoảng 4000 hàng.
    • Định nghĩa (ít nhất là một phần) là:

      SELECT AVG([AD_Sensor_Data])
                 OVER (ORDER BY [RowID] ROWS BETWEEN 5 PRECEDING AND 5 FOLLOWING)
                 as 'AD_Sensor_Data'
      FROM   [AD_Points]
      WHERE  [FileID] = @FileID
      ORDER BY [RowID] ASC

Những gì chúng ta có thể phỏng đoán:

Tiếp theo, chúng ta có thể cùng nhau xem xét tất cả các điểm dữ liệu này để xem liệu chúng ta có thể tổng hợp các chi tiết bổ sung sẽ giúp chúng ta tìm thấy một hoặc nhiều cổ chai hay không, hoặc hướng tới một giải pháp, hoặc ít nhất là loại trừ một số giải pháp có thể.

Hướng suy nghĩ hiện tại trong các ý kiến ​​là vấn đề chính là truyền dữ liệu giữa SQL Server và Excel. Đó thực sự là trường hợp? Nếu Quy trình được lưu trữ được gọi cho mỗi trong số 800.000 hàng và mất 50 ms cho mỗi cuộc gọi (tức là mỗi hàng), điều đó sẽ tăng thêm tới 40.000 giây (không phải ms). Và nó tương đương với 666 phút (hhmm ;-), hoặc chỉ hơn 11 giờ. Tuy nhiên, toàn bộ quá trình được cho là chỉ mất 7 giờ để chạy. Chúng tôi đã có 4 giờ trong tổng thời gian và chúng tôi thậm chí đã thêm kịp thời để thực hiện các tính toán hoặc lưu kết quả trở lại SQL Server. Vì vậy, một cái gì đó không phải là ở đây.

Nhìn vào định nghĩa của Thủ tục lưu trữ, chỉ có một tham số đầu vào cho @FileID; không có bộ lọc nào trên @RowID. Vì vậy, tôi nghi ngờ rằng một trong hai kịch bản sau đây đang xảy ra:

  • Quy trình được lưu trữ này không thực sự được gọi cho mỗi hàng, mà thay vào đó mỗi thủ tục @FileID, dường như kéo dài khoảng 4000 hàng. Nếu 4000 hàng đã nêu được trả về là một số tiền khá phù hợp, thì chỉ có 200 trong số đó được nhóm trong 800.000 hàng. Và 200 lần thực hiện mất 50 ms mỗi lần chỉ trong 10 giây trong 7 giờ đó.
  • Nếu quy trình được lưu trữ này thực sự được gọi cho mỗi hàng, thì lần đầu tiên một giao dịch mới @FileIDsẽ được thực hiện lâu hơn một chút để kéo các hàng mới vào Vùng đệm, nhưng sau đó, các thực thi 3999 tiếp theo thường sẽ quay lại nhanh hơn do đã được thực hiện lưu trữ, phải không?

Tôi nghĩ rằng việc tập trung vào Quy trình lưu trữ "bộ lọc" này hoặc bất kỳ việc truyền dữ liệu nào từ SQL Server sang Excel, là một cá trích đỏ .

Hiện tại, tôi nghĩ các chỉ số phù hợp nhất về hiệu suất mờ nhạt là:

  • Có 800.000 hàng
  • Hoạt động trên một hàng tại một thời điểm
  • Dữ liệu đang được lưu trở lại SQL Server, do đó "[sử dụng] giá trị từ một số cột để thao tác với các cột khác " [ phas em của tôi là ;-)]

Tôi nghi ngờ rằng:

  • trong khi có một số chỗ để cải thiện việc truy xuất dữ liệu và tính toán, làm cho những điều đó tốt hơn sẽ không làm giảm đáng kể thời gian xử lý.
  • nút thắt lớn đang phát hành 800.000 UPDATEbáo cáo riêng biệt , đó là 800.000 giao dịch riêng biệt.

Đề xuất của tôi (dựa trên thông tin hiện có):

  1. Khu vực cải tiến lớn nhất của bạn sẽ là cập nhật nhiều hàng cùng một lúc (nghĩa là trong một giao dịch). Bạn nên cập nhật quy trình của bạn để làm việc theo từng FileIDthay vì từng RowID. Vì thế:

    1. đọc trong tất cả 4000 hàng cụ thể FileIDthành một mảng
    2. mảng nên chứa các phần tử đại diện cho các trường đang được thao tác
    3. quay vòng qua mảng, xử lý từng hàng như bạn hiện đang làm
    4. một khi tất cả các hàng trong mảng (nghĩa là cụ thể này FileID) đã được tính toán:
      1. bắt đầu một giao dịch
      2. gọi mỗi bản cập nhật cho mỗi RowID
      3. nếu không có lỗi, cam kết giao dịch
      4. nếu xảy ra lỗi, khôi phục và xử lý thích hợp
  2. Nếu chỉ mục được nhóm của bạn chưa được xác định như vậy (FileID, RowID)thì bạn nên xem xét điều đó (như @MikaelEriksson đã đề xuất trong một nhận xét về Câu hỏi). Nó sẽ không giúp những CẬP NHẬT đơn lẻ này, nhưng ít nhất nó sẽ cải thiện một chút các hoạt động tổng hợp, chẳng hạn như những gì bạn đang làm trong quy trình lưu trữ "bộ lọc" đó vì tất cả đều dựa trên FileID.

  3. Bạn nên xem xét việc chuyển logic sang ngôn ngữ được biên dịch. Tôi sẽ đề nghị tạo một ứng dụng .NET WinForms hoặc thậm chí cả Ứng dụng Console. Tôi thích Ứng dụng Console vì dễ dàng lên lịch thông qua Tác nhân SQL hoặc Tác vụ theo lịch của Windows. Không quan trọng là nó được thực hiện trong VB.NET hay C #. VB.NET có thể phù hợp tự nhiên hơn cho nhà phát triển của bạn, nhưng vẫn sẽ có một số đường cong học tập.

    Tôi không thấy bất kỳ lý do tại thời điểm này để chuyển sang SQLCLR. Nếu thuật toán thay đổi thường xuyên, điều đó sẽ gây khó chịu khi phải triển khai lại Hội đồng mọi lúc. Xây dựng lại ứng dụng Console và đặt .exe vào thư mục chia sẻ thích hợp trên mạng để bạn chỉ chạy cùng một chương trình và nó luôn luôn cập nhật, khá dễ thực hiện.

    Tôi không nghĩ việc chuyển việc xử lý hoàn toàn sang T-SQL sẽ giúp ích nếu vấn đề là điều tôi nghi ngờ và bạn chỉ đang thực hiện một CẬP NHẬT một lần.

  4. Nếu quá trình xử lý được chuyển sang .NET, thì bạn có thể sử dụng Tham số có giá trị bảng (TVP) để bạn chuyển mảng vào Quy trình được lưu trữ sẽ gọi một THAM GIA UPDATEđến biến bảng TVP và do đó chỉ là một giao dịch . TVP phải nhanh hơn thực hiện 4000 INSERTgiây được nhóm thành một giao dịch. Nhưng lợi ích đến từ việc sử dụng TVP trên 4000 INSERTgiây trong 1 giao dịch có thể sẽ không đáng kể bằng sự cải thiện được thấy khi chuyển từ 800.000 giao dịch riêng lẻ sang chỉ 200 giao dịch mỗi 4000 hàng.

    Tùy chọn TVP không có sẵn cho phía VBA, nhưng ai đó đã nghĩ ra một cách giải quyết có thể đáng để thử nghiệm:

    Làm cách nào để cải thiện hiệu suất cơ sở dữ liệu khi chuyển từ VBA sang SQL Server 2008 R2?

  5. NẾU bộ lọc Proc chỉ sử dụng FileIDtrong WHEREmệnh đề và NẾU Proc thực sự được gọi cho mỗi hàng, thì bạn có thể tiết kiệm thời gian xử lý bằng cách lưu trữ kết quả của lần chạy đầu tiên và sử dụng chúng cho phần còn lại của hàng đó FileID, đúng?

  6. Khi bạn đã xử lý xong mỗi FileID , thì chúng ta có thể bắt đầu nói về xử lý song song. Nhưng điều đó có thể không cần thiết ở thời điểm đó :). Cho rằng bạn đang xử lý 3 phần không chính lý tưởng: giao dịch Excel, VBA và 800k, bất kỳ cuộc thảo luận nào về SSIS, hoặc hình bình hành, hoặc ai biết, là tối ưu hóa sớm / công cụ loại giỏ hàng trước . Nếu chúng tôi có thể giảm quá trình 7 giờ này xuống còn 10 phút hoặc ít hơn, bạn vẫn sẽ nghĩ đến những cách bổ sung để làm cho nó nhanh hơn chứ? Có một thời gian hoàn thành mục tiêu mà bạn có trong tâm trí? Hãy nhớ rằng một khi quá trình xử lý được thực hiện trên mỗi FileID về cơ bản, nếu bạn đã có Ứng dụng Bảng điều khiển VB.NET (ví dụ: dòng lệnh .EXE), sẽ không có gì ngăn bạn chạy một vài FileID đó một lúc :), cho dù thông qua bước CmdExec của Tác nhân SQL hoặc Nhiệm vụ theo lịch trình của Windows, Vân vân.

VÀ, bạn luôn có thể thực hiện một cách tiếp cận "theo giai đoạn" và thực hiện một vài cải tiến tại một thời điểm. Chẳng hạn như bắt đầu với việc thực hiện các cập nhật cho mỗi FileIDvà do đó sử dụng một giao dịch cho nhóm đó. Sau đó, xem bạn có thể làm cho TVP hoạt động không. Sau đó, hãy xem về việc lấy mã đó và chuyển nó sang VB.NET (và TVP hoạt động trong .NET để nó sẽ chuyển tốt).


Những gì chúng ta không biết vẫn có thể giúp:

  • "Bộ lọc" Quy trình được lưu trữ chạy trên RowID hoặc mỗi FileID ? Chúng ta thậm chí có định nghĩa đầy đủ về Thủ tục lưu trữ đó không?
  • Lược đồ đầy đủ của bảng. Cái bàn này rộng bao nhiêu? Có bao nhiêu trường có chiều dài thay đổi? Có bao nhiêu lĩnh vực là NULLable? Nếu có NULLable thì có bao nhiêu NULL?
  • Các chỉ mục cho bảng này. Có phân vùng không? Là nén ROW hoặc PAGE đang được sử dụng?
  • Bảng này lớn đến mức nào về MB / GB?
  • Làm thế nào là bảo trì chỉ mục được xử lý cho bảng này? Làm thế nào phân mảnh được các chỉ số? Làm thế nào cập nhật cho đến nay là số liệu thống kê?
  • Có bất kỳ quy trình nào khác ghi vào bảng này trong khi quá trình 7 giờ này đang diễn ra không? Nguồn có thể tranh chấp.
  • Có bất kỳ quá trình khác đọc từ bảng này trong khi quá trình 7 giờ này đang diễn ra? Nguồn có thể tranh chấp.

CẬP NHẬT 1:

** Dường như có một số nhầm lẫn về những gì VBA (Visual Basic cho Ứng dụng) và những gì có thể được thực hiện với nó, vì vậy điều này chỉ để đảm bảo tất cả chúng ta đều trên cùng một trang web:


CẬP NHẬT 2:

Thêm một điểm để xem xét: Làm thế nào các kết nối được xử lý? Là mã VBA mở và đóng Kết nối cho mỗi hoạt động, hay nó mở kết nối khi bắt đầu quá trình và đóng nó ở cuối quá trình (tức là 7 giờ sau)? Ngay cả với nhóm kết nối (theo mặc định, nên được bật cho ADO), vẫn sẽ có một tác động khá lớn giữa mở và đóng một lần thay vì mở và đóng 800.200 hoặc 1.600.000 lần. Các giá trị này dựa trên ít nhất 800.000 CẬP NHẬT cộng với 200 hoặc 800 nghìn EXEC (tùy thuộc vào tần suất bộ lọc được lưu trữ thực sự được thực thi).

Vấn đề có quá nhiều kết nối này sẽ tự động được giảm thiểu theo khuyến nghị tôi đã nêu ở trên. Bằng cách tạo một giao dịch và thực hiện tất cả các CẬP NHẬT trong giao dịch đó, bạn sẽ giữ kết nối đó mở và sử dụng lại cho mỗi giao dịch UPDATE. Việc kết nối có được duy trì mở từ cuộc gọi ban đầu để nhận 4000 hàng trên mỗi lần chỉ định FileIDhay đã đóng sau thao tác "get" đó và mở lại cho các CẬP NHẬT, ít ảnh hưởng hơn vì chúng ta hiện đang nói về sự khác biệt của một trong hai 200 hoặc 400 tổng số kết nối trên toàn bộ quá trình.

CẬP NHẬT 3:

Tôi đã làm một số thử nghiệm nhanh chóng. Xin lưu ý rằng đây là một thử nghiệm quy mô khá nhỏ và không phải là hoạt động chính xác giống nhau (thuần túy INSERT so với EXEC + CẬP NHẬT). Tuy nhiên, sự khác biệt về thời gian liên quan đến cách xử lý các kết nối và giao dịch vẫn có liên quan, do đó thông tin có thể được ngoại suy để có tác động tương đối giống nhau ở đây.

Thông số kiểm tra:

  • Phiên bản dành cho nhà phát triển SQL Server 2012 (64-bit), SP2
  • Bàn:

     CREATE TABLE dbo.ManyInserts
     (
        RowID INT NOT NULL IDENTITY(1, 1) PRIMARY KEY,
        InsertTime DATETIME NOT NULL DEFAULT (GETDATE()),
        SomeValue BIGINT NULL
     );
  • Hoạt động:

    INSERT INTO dbo.ManyInserts (SomeValue) VALUES ({LoopIndex * 12});
  • Tổng số chèn cho mỗi bài kiểm tra: 10.000
  • Đặt lại cho mỗi thử nghiệm: TRUNCATE TABLE dbo.ManyInserts;(với bản chất của thử nghiệm này, thực hiện FREEPROCCACHE, FREESYSTEMCACHE và DROPCLEANBUFFERS dường như không thêm nhiều giá trị.)
  • Mô hình khôi phục: SIMPLE (và có thể 1 GB miễn phí trong tệp Nhật ký)
  • Các thử nghiệm sử dụng Giao dịch chỉ sử dụng một Kết nối duy nhất bất kể có bao nhiêu Giao dịch.

Các kết quả:

Test                                   Milliseconds
-------                                ------------
10k INSERTs across 10k Connections     3968 - 4163
10k INSERTs across 1 Connection        3466 - 3654
10k INSERTs across 1 Transaction       1074 - 1086
10k INSERTs across 10 Transactions     1095 - 1169

Như bạn có thể thấy, ngay cả khi kết nối ADO với DB đã được chia sẻ trên tất cả các hoạt động, việc nhóm chúng thành các đợt bằng một giao dịch rõ ràng (đối tượng ADO sẽ có thể xử lý việc này) được đảm bảo đáng kể (tức là cải thiện hơn 2 lần) giảm thời gian xử lý tổng thể.


Có một cách tiếp cận "người trung gian" tuyệt vời với những gì srutzky đang đề xuất và đó là sử dụng PowerShell để lấy dữ liệu bạn cần từ SQL Server, gọi tập lệnh VBA của bạn để xử lý dữ liệu và sau đó gọi SP cập nhật trong SQL Server , chuyển các khóa và giá trị cập nhật trở lại máy chủ SQL. Theo cách này, bạn kết hợp một cách tiếp cận dựa trên tập hợp với những gì bạn đã có.
Steve Mangiameli

@SteveMangiameli Chào Steve và cảm ơn vì nhận xét. Tôi đã trả lời sớm hơn nhưng đã bị bệnh. Tôi tò mò không biết ý tưởng của bạn khác nhiều so với những gì tôi đang đề xuất. Tất cả các dấu hiệu cho thấy Excel vẫn được yêu cầu để chạy VBA. Hoặc bạn đang đề xuất rằng PowerShell sẽ thay thế ADO và nếu I / O nhanh hơn nhiều, sẽ có giá trị ngay cả khi chỉ thay thế I / O?
Solomon Rutzky

1
Không phải lo lắng, vui mừng cảm giác của bạn tốt hơn. Tôi không biết rằng nó sẽ tốt hơn. Chúng tôi không biết những gì chúng tôi không biết và bạn đã thực hiện một số phân tích tuyệt vời nhưng vẫn phải đưa ra một số giả định. I / O có thể đủ quan trọng để tự thay thế; chúng tôi chỉ không biết. Tôi chỉ muốn trình bày một cách tiếp cận khác có thể hữu ích với những điều bạn đã đề xuất.
Steve Mangiameli

@SteveMangiameli Cảm ơn. Và cảm ơn bạn đã làm rõ điều đó. Tôi không chắc chắn về hướng chính xác của bạn và cho rằng tốt nhất không nên giả định. Có, tôi đồng ý rằng có nhiều lựa chọn hơn sẽ tốt hơn vì chúng tôi không biết những ràng buộc nào đối với những thay đổi có thể được thực hiện :).
Solomon Rutzky

Hey srutzky, cảm ơn vì những suy nghĩ chi tiết! Tôi đã trở lại thử nghiệm về phía SQL để nhận được các chỉ mục và truy vấn được tối ưu hóa và cố gắng tìm ra các nút thắt cổ chai. Bây giờ tôi đã đầu tư vào một máy chủ thích hợp, 36 lõi SSD, 1TB đã loại bỏ các ổ SSD PCIe khi IO bị sa lầy. Bây giờ hãy gọi mã VB trực tiếp trong SSIS, có vẻ như mở nhiều luồng để thực thi song song.
medwar19

2

IMHO và làm việc từ giả định rằng không thể mã hóa lại phụ VBA thành SQL, bạn đã xem xét cho phép tập lệnh VBA hoàn thành việc đánh giá trong tệp Excel và sau đó ghi lại kết quả cho máy chủ SQL qua SSIS chưa?

Bạn có thể bắt đầu và kết thúc phụ VBA bằng cách lật một chỉ báo trong đối tượng hệ thống tệp hoặc trong máy chủ (nếu bạn đã định cấu hình kết nối để ghi lại vào máy chủ) và sau đó sử dụng biểu thức SSIS để kiểm tra chỉ báo này cho disablethuộc tính của một tác vụ nhất định trong giải pháp SSIS của bạn (để quá trình nhập chờ cho đến khi phụ VBA hoàn thành nếu bạn lo lắng về việc vượt quá lịch trình của nó).

Ngoài ra, bạn có thể để tập lệnh VBA khởi động theo chương trình (một chút rắc rối, nhưng tôi đã sử dụng thuộc workbook_open()tính để kích hoạt các nhiệm vụ "bắn và quên" về bản chất này trong quá khứ).

Nếu thời gian đánh giá của tập lệnh VB bắt đầu trở thành một vấn đề, bạn có thể xem liệu nhà phát triển VB của bạn có sẵn sàng và có thể chuyển mã của mình thành một tác vụ tập lệnh VB trong giải pháp SSIS hay không - theo kinh nghiệm của tôi, ứng dụng Excel sẽ mất rất nhiều chi phí khi làm việc với dữ liệu ở khối lượng này.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.